# Study.py -- Pamhyr study checkers
# Copyright (C) 2023  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 time

from PyQt5.QtCore import QCoreApplication

from Checker.Checker import AbstractModelChecker, STATUS

_translate = QCoreApplication.translate


class StudyNetworkReachChecker(AbstractModelChecker):
    def __init__(self):
        super(StudyNetworkReachChecker, self).__init__()

        self._name = _translate("Checker", "Study network reach checker")
        self._description = _translate(
            "Checker", "Check if exists at least one reach for study")

    def run(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

        edges = list(filter(lambda e: e.is_enable(), river.edges()))
        if len(edges) == 0:
            self._status = STATUS.ERROR
            self._summary = "no_reach_defined"
            return False

        self._summary = "ok"
        self._status = STATUS.OK
        return True


class StudyGeometryChecker(AbstractModelChecker):
    def __init__(self):
        super(StudyGeometryChecker, self).__init__()

        self._name = _translate("Checker", "Study geometry checker")
        self._description = _translate(
            "Checker", "Check if exists geometry for each reach of study")
        self._reachs = []

    def run(self, study):
        ok = True
        nerror = 0
        summary = "ok"
        status = STATUS.OK

        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

        edges = list(filter(lambda e: e.is_enable(), river.edges()))
        if len(edges) == 0:
            self._status = STATUS.ERROR
            self._summary = "no_reach_defined"
            return False

        for edge in edges:
            if edge.is_enable() and len(edge.reach.profiles) < 3:
                summary = f"no_geometry_defined"
                status = STATUS.ERROR
                ok = False
                self._reachs.append(edge)

        self._summary = summary
        self._status = status
        return ok


class DummyOK(AbstractModelChecker):
    def __init__(self):
        super(DummyOK, self).__init__()

        self._name = _translate("Checker", "Dummy ok")
        self._description = _translate("Checker", "Dummy ok")

    def run(self, study):
        time.sleep(1)

        self._summary = "ok"
        self._status = STATUS.OK

        return True


class DummyWARNING(AbstractModelChecker):
    def __init__(self):
        super(DummyWARNING, self).__init__()

        self._name = _translate("Checker", "Dummy warning")
        self._description = _translate("Checker", "Dummy warning")

    def run(self, study):
        time.sleep(1)

        self._summary = "Warning detected"
        self._status = STATUS.WARNING

        return True


class DummyERROR(AbstractModelChecker):
    def __init__(self):
        super(DummyERROR, self).__init__()

        self._name = _translate("Checker", "Dummy error")
        self._description = _translate("Checker", "Dummy error")

    def run(self, study):
        time.sleep(1)

        self._summary = "Error detected"
        self._status = STATUS.ERROR
        return True
