#    Copyright (C) 2021 Andrei Puchko
#
#    Licensed under the Apache License, Version 2.0 (the "License");
#    you may not use this file except in compliance with the License.
#    You may obtain a copy of the License at
# 
#        http://www.apache.org/licenses/LICENSE-2.0
# 
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.
"""

"""
if __name__ == "__main__":
    import sys

    sys.path.insert(0, ".")

    from tests import test_schema

    test_schema.test_schema()

    from demo import demo_01

    demo_01.demo()


class ZzDbSchema:
    """
    {"tables": {"table_name": {"columns": {}, "indexes": {...}}}}
    """

    def __init__(self, schema={}):
        self.schema = {"tables": {}}

    def add(
        self,
        table="",
        column="",
        datatype=None,
        datalen=None,
        datadec=None,
        to_table=None,
        to_column=None,
        related=None,
        pk=None,
        ai=None,
        uk=None,
    ):
        """
        table - database table name

        column - column name
        datatype - type
        datalen - lenght
        datadec - decimal precison

        to_table - foreign key table
        to_column -  foreign key column
        related - ?foreign column to show

        pk - primary key
        ai - autoincrement
        uk - unique
        """
        if not (table or column):
            return
        if table not in self.schema["tables"]:
            self.schema["tables"][table] = {"columns": {}, "indexes": {}}
        self.schema["tables"][table]["columns"][column] = {}

        self.schema["tables"][table]["columns"][column]["datatype"] = datatype
        self.schema["tables"][table]["columns"][column]["datalen"] = datalen
        self.schema["tables"][table]["columns"][column]["datadec"] = datadec
        self.schema["tables"][table]["columns"][column]["to_table"] = to_table
        self.schema["tables"][table]["columns"][column]["to_column"] = to_column
        self.schema["tables"][table]["columns"][column]["related"] = related
        self.schema["tables"][table]["columns"][column]["pk"] = pk
        self.schema["tables"][table]["columns"][column]["ai"] = ai
        self.schema["tables"][table]["columns"][column]["uk"] = uk

    def get_schema_table_attr(self, table="", column="", attr=""):
        """
        returs schema data for given table, column, attribute
            get_schema_table_attr(table_name) - all columns
            get_schema_table_attr(table_name,column_name) - given column
            get_schema_table_attr(table_name,column_name,"datalen") - given attribute
        """
        rez = self.schema.get("tables", {})
        if table == "":
            return rez
        rez = rez.get(table, {}).get("columns", {})
        if column == "":
            return rez
        rez = rez.get(column, {})
        if attr == "":
            return rez
        return rez.get(attr, "")

    def get_primary_tables(self, child_table, child_record):
        """
        returns list of foreign key tables and columns
        for given 'child_table' and 'child_record'

        used by ZzDb for integrity checking when INSERT/UPDATE
        """
        rez = []
        for child_column_name in self.get_schema_table_attr(child_table):
            child_column = self.get_schema_table_attr(child_table, child_column_name)
            if child_column.get("to_table") and child_column.get("to_column"):
                rez.append(
                    {
                        "primary_table": child_column.get("to_table"),
                        "primary_column": child_column.get("to_column"),
                        "child_column": child_column_name,
                        "child_value": child_record.get(child_column_name, ""),
                    }
                )
        return rez

    def get_child_tables(self, primary_table, primary_record):
        """
        returns list of foreign key tables and columns
        for given 'primary_table' and 'primary_record'

        used by ZzDb for integrity checking when DELETE
        """
        rez = []
        for linked_table_name in self.get_schema_table_attr():
            for linked_column_name in self.get_schema_table_attr(linked_table_name):
                linked_column = self.get_schema_table_attr(linked_table_name, linked_column_name)
                if linked_column.get("to_table") == primary_table and linked_column.get("to_column"):
                    parentCol = linked_column.get("to_column")
                    rez.append(
                        {
                            "child_table": linked_table_name,
                            "child_column": linked_column_name,
                            "parent_column": parentCol,
                            "parent_value": primary_record.get(parentCol),
                        }
                    )
        return rez
