# Value.py -- Pamhyr
# Copyright (C) 2023-2024  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 -*-

from Model.Tools.PamhyrDB import SQLSubModel


class BHSValue(SQLSubModel):
    _sub_classes = []
    _id_cnt = 0

    def __init__(self, name: str = "", type=float, value=0.0,
                 status=None):
        super(BHSValue, self).__init__()

        self._status = status

        self._name = name
        self._type = type
        self._value = type(value)

    @classmethod
    def _db_create(cls, execute):
        execute("""
          CREATE TABLE hydraulic_structures_basic_value(
            id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            type TEXT NOT NULL,
            value TEXT NOT NULL,
            bhs INTEGER,
            FOREIGN KEY(bhs) REFERENCES hydraulic_structures_basic(id)
          )
        """)

        return cls._create_submodel(execute)

    @classmethod
    def _db_update(cls, execute, version):
        major, minor, release = version.strip().split(".")
        if major == minor == "0":
            if int(release) < 6:
                cls._db_create(execute)

        return True

    @classmethod
    def _str_to_type(cls, type):
        res = str

        if type == "float":
            res = float
        elif type == "int":
            res = int
        elif type == "bool":
            res = bool

        return res

    @classmethod
    def _type_to_str(cls, type):
        res = "str"

        if type == float:
            res = "float"
        elif type == int:
            res = "int"
        elif type == bool:
            res = "bool"

        return res

    @classmethod
    def _db_load(cls, execute, data=None):
        new = []
        bhs_id = data["bhs_id"]

        table = execute(
            "SELECT name, type, value " +
            "FROM hydraulic_structures_basic_value " +
            f"WHERE bhs = '{bhs_id}'"
        )

        for row in table:
            name = row[0]
            type = cls._str_to_type(row[1])
            value = row[2]

            val = cls(
                name=name,
                type=type,
                value=value,
                status=data['status']
            )

            new.append(val)

        return new

    def _db_save(self, execute, data=None):
        bhs_id = data["bhs_id"]

        sql = (
            "INSERT INTO " +
            "hydraulic_structures_basic_value(name, type, value, bhs) " +
            "VALUES (" +
            f"'{self._db_format(self._name)}', " +
            f"'{self._db_format(self._type_to_str(self._type))}', " +
            f"'{self._db_format(self._value)}', " +
            f"{bhs_id}" +
            ")"
        )
        execute(sql)

        return True

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

    @property
    def type(self):
        return self._type

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, value):
        self._value = self._type(value)
        self._status.modified()
