# SPDX-FileCopyrightText: Copyright 2020-2021 Arm Limited and/or its affiliates <open-source-office@arm.com>
#
# SPDX-License-Identifier: Apache-2.0
#
# 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
#
# 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.
import csv
import io
from typing import Any
from typing import Dict
from typing import List
from typing import Tuple
from typing import Union

import lxml.etree as xml

from . import numeric_util
from .operation import Operation
from .shape4d import Shape4D


class DebugDatabase:
    NULLREF = -1
    show_warnings = False

    SOURCE_TABLE = "source"
    _sourceUID: Dict[Any, int] = {}
    _sourceHeaders = ["id", "operator", "kernel_w", "kernel_h", "ofm_w", "ofm_h", "ofm_d"]
    _sourceTable: List[List[Union[float, int, str]]] = []

    OPTIMISED_TABLE = "optimised"
    _optimisedUID: Dict[Any, Tuple[int, int]] = {}
    _optimisedHeaders = ["id", "source_id", "operator", "kernel_w", "kernel_h", "ofm_w", "ofm_h", "ofm_d"]
    _optimisedTable: List[List[Union[float, int, str]]] = []

    QUEUE_TABLE = "queue"
    _queueHeaders = ["offset", "cmdstream_id", "optimised_id"]
    _queueTable: List[List[int]] = []

    STREAM_TABLE = "cmdstream"
    _streamUID: Dict[Any, int] = {}
    _streamHeaders = ["id", "file_offset"]
    _streamTable: List[List[int]] = []

    @classmethod
    def add_source(cls, op: Operation):
        assert isinstance(op, Operation)
        uid = len(cls._sourceUID)
        cls._sourceUID[op] = uid
        ofm_shape = numeric_util.full_shape(3, op.outputs[0].shape, 1)
        cls._sourceTable.append(
            [uid, str(op.type), op.kernel.width, op.kernel.height, ofm_shape[-2], ofm_shape[-3], ofm_shape[-1]]
        )

    @classmethod
    def add_optimised(cls, parent: Operation, op: Operation):
        assert isinstance(parent, Operation) and isinstance(op, Operation)
        if op not in cls._optimisedUID:
            if parent not in cls._sourceUID:
                # The the parent wasn't in the source network try to look it
                # up in the optimised network and use that op's source parent.
                if parent in cls._optimisedUID:
                    src_uid = cls._optimisedUID[parent][1]
                else:
                    if DebugDatabase.show_warnings:
                        print("Debug Database: Associated parent '{0}' not in network".format(parent.type))
                    src_uid = DebugDatabase.NULLREF
            else:
                src_uid = cls._sourceUID[parent]
            uid = len(cls._optimisedUID)
            cls._optimisedUID[op] = (uid, src_uid)
            if len(op.ofm_shapes) == 0:
                ofm_shape = Shape4D(op.outputs[0].shape)
            else:
                ofm_shape = op.ofm_shapes[0]
            cls._optimisedTable.append(
                [
                    uid,
                    src_uid,
                    str(op.type),
                    op.kernel.width,
                    op.kernel.height,
                    ofm_shape.width,
                    ofm_shape.height,
                    ofm_shape.depth,
                ]
            )

    @classmethod
    def add_stream(cls, key):
        if key not in cls._streamUID:
            uid = len(cls._streamUID)
            cls._streamUID[key] = uid
        return uid

    @classmethod
    def set_stream_offset(cls, key, file_offset: int):
        assert key in cls._streamUID
        uid = cls._streamUID[key]
        cls._streamTable.append([uid, file_offset])

    @classmethod
    def add_command(cls, stream_id: int, offset: int, op: Operation):
        assert stream_id < len(cls._streamUID)
        assert op in cls._optimisedUID, "Optimised operator must exist before code generation"
        optimised_id = cls._optimisedUID[op][0]
        cls._queueTable.append([offset, stream_id, optimised_id])

    @classmethod
    def _write_table(cls, root: xml.Element, name: str, headers: List[str], table):
        # Convert table to CSV
        out = io.StringIO()
        writer = csv.writer(out, quoting=csv.QUOTE_NONNUMERIC)
        writer.writerow(headers)
        writer.writerows(table)

        # Package table into XML output
        table = xml.SubElement(root, "table", {"name": name})
        table.text = xml.CDATA(out.getvalue())

    @classmethod
    def write(cls, file_path: str, input_file: str, output_file: str):
        root = xml.Element("debug", {"source": input_file, "optimised": output_file})

        cls._write_table(root, cls.SOURCE_TABLE, cls._sourceHeaders, cls._sourceTable)
        cls._write_table(root, cls.OPTIMISED_TABLE, cls._optimisedHeaders, cls._optimisedTable)
        cls._write_table(root, cls.QUEUE_TABLE, cls._queueHeaders, cls._queueTable)
        cls._write_table(root, cls.STREAM_TABLE, cls._streamHeaders, cls._streamTable)

        xml.ElementTree(root).write(file_path, encoding="utf-8", xml_declaration=True, pretty_print=True)
