# Checker.py -- Pamhyr abstract checker class
# Copyright (C) 2023-2026  INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

# -*- coding: utf-8 -*-

import logging

from enum import Enum

from Modules import Modules
from Model.Except import NotImplementedMethodeError

logger = logging.getLogger()


class STATUS(Enum):
    OK = 0
    WARNING = 1
    ERROR = 2
    UNKNOWN = 999

    def __eq__(self, y):
        return self.value == y.value

    def __gt__(self, y):
        return self.value > y.value

    def __or__(self, y):
        v = [self, y]
        r = self.OK

        if self.UNKNOWN in v:
            r = self.UNKNOWN
        if self.ERROR in v:
            r = self.ERROR
        if self.WARNING in v:
            r = self.WARNING

        logger.debug(f"CHECKER: STATUS: {self} | {y} = {r}")
        return r


class AbstractModelChecker(object):
    def __init__(self):
        self._name = ""
        self._description = ""
        self._solver = "study"
        self._modules = Modules.NONE

        self.reset()

    def reset(self):
        self._status = STATUS.UNKNOWN
        self._summary = "Unknown"

    @property
    def name(self):
        return self._name

    @property
    def description(self):
        return self._description

    @property
    def summary(self):
        return self._summary

    # Checker status

    def is_unknown(self):
        return self._status == STATUS.UNKNOWN

    def is_ok(self):
        return self._status == STATUS.OK

    def is_warning(self):
        return self._status == STATUS.WARNING

    def is_error(self):
        return self._status == STATUS.ERROR

    # Basic check
    def basic_check(self, study):
        if study is None:
            self._status = STATUS.ERROR
            self._summary = "invalid_study"
            return False

        river = study.river
        if river is None:
            self._status = STATUS.ERROR
            self._summary = "no_river_found"
            return False

        return True

    # Abstract function

    def _run(self, study):
        from Model.Study import Study

        thread_study = Study.open(study._filename)
        self.run(thread_study)

    def run(self, study):
        """Run checker function

        Args:
            study: The study to check

        Returns:
            Return true if study is valid for this checker, false
            otherelse
        """
        raise NotImplementedMethodeError(self, self.run)
