# Copyright (c) 2022 Project CHIP Authors
#
# 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.

import enum
from dataclasses import dataclass
from typing import List, Optional, Union

from matter_idl import matter_idl_types  # to explicitly say 'Enum'
from matter_idl.matter_idl_types import DataType


def ToPowerOfTwo(bits: int) -> int:
    """
    Given a number, find the next power of two that is >= to the given value.

    Can be used to figure out a variable size given non-standard bit sizes in
    matter: eg. a int24 can be stored in an int32, so ToPortOfTwo(24) == 32.

    """
    # probably bit manipulation can be faster, but this should be ok as well
    result = 1
    while result < bits:
        result = result * 2
    return result


@dataclass
class BasicInteger:
    """
    Represents something that is stored as a basic integer.
    """
    idl_name: str
    byte_count: int  # NOTE: may NOT be a power of 2 for odd sized integers
    is_signed: bool

    @property
    def bits(self):
        return self.byte_count * 8

    @property
    def power_of_two_bits(self):
        return ToPowerOfTwo(self.bits)


@dataclass
class BasicString:
    """
    Represents either a string or a binary string (blob).
    """
    idl_name: str
    is_binary: bool
    max_length: Union[int, None] = None


class FundamentalType(enum.Enum):
    """
    Native types, generally available across C++/ObjC/Java/python/other.
    """
    BOOL = enum.auto()
    FLOAT = enum.auto()
    DOUBLE = enum.auto()

    @property
    def idl_name(self):
        if self == FundamentalType.BOOL:
            return "bool"
        elif self == FundamentalType.FLOAT:
            return "single"
        elif self == FundamentalType.DOUBLE:
            return "double"
        else:
            raise Error("Type not handled: %r" % self)

    @property
    def byte_count(self):
        if self == FundamentalType.BOOL:
            return 1
        elif self == FundamentalType.FLOAT:
            return 4
        elif self == FundamentalType.DOUBLE:
            return 8
        else:
            raise Error("Type not handled: %r" % self)

    @property
    def bits(self):
        return self.byte_count * 8


@dataclass
class IdlEnumType:
    """
    An enumeration type. Enumerations are constants with an underlying
    base type that is an interger.
    """
    idl_name: str
    base_type: BasicInteger

    @property
    def byte_count(self):
        return base_type.byte_count()

    @property
    def bits(self):
        return base_type.bits()


@dataclass
class IdlBitmapType:
    """
    Bitmaps mark that each bit (or a subset of said bits) have a meaning.

    Examples include "feature maps" where bits represent feature available or not.
    """
    idl_name: str
    base_type: BasicInteger

    @property
    def byte_count(self):
        return base_type.byte_count()

    @property
    def bits(self):
        return base_type.bits()


class IdlItemType(enum.Enum):
    UNKNOWN = enum.auto()
    STRUCT = enum.auto()


@dataclass
class IdlType:
    """
    A type defined within the IDL.

    IDLs would generally only define structures as all other types are
    described in other things like enums/bitmaps/basic types etc.

    However since IDL parsing is not yet codegen just syntactically, we allow
    the option to have a type that is marked 'unknown' (likely invalid/never
    defined).
    """
    idl_name: str
    item_type: IdlItemType

    @property
    def is_struct(self) -> bool:
        return self.item_type == IdlItemType.STRUCT


# Data types, held by ZAP in chip-types.xml and generally by the spec.
__CHIP_SIZED_TYPES__ = {
    "bitmap16": BasicInteger(idl_name="bitmap16", byte_count=2, is_signed=False),
    "bitmap24": BasicInteger(idl_name="bitmap24", byte_count=3, is_signed=False),
    "bitmap32": BasicInteger(idl_name="bitmap32", byte_count=4, is_signed=False),
    "bitmap64": BasicInteger(idl_name="bitmap64", byte_count=8, is_signed=False),
    "bitmap8": BasicInteger(idl_name="bitmap8", byte_count=1, is_signed=False),
    "enum16": BasicInteger(idl_name="enum16", byte_count=2, is_signed=False),
    "enum32": BasicInteger(idl_name="enum32", byte_count=4, is_signed=False),
    "enum8": BasicInteger(idl_name="enum8", byte_count=1, is_signed=False),
    "int16s": BasicInteger(idl_name="int16s", byte_count=2, is_signed=True),
    "int16u": BasicInteger(idl_name="int16u", byte_count=2, is_signed=False),
    "int24s": BasicInteger(idl_name="int24s", byte_count=3, is_signed=True),
    "int24u": BasicInteger(idl_name="int24u", byte_count=3, is_signed=False),
    "int32s": BasicInteger(idl_name="int32s", byte_count=4, is_signed=True),
    "int32u": BasicInteger(idl_name="int32u", byte_count=4, is_signed=False),
    "int40s": BasicInteger(idl_name="int40s", byte_count=5, is_signed=True),
    "int40u": BasicInteger(idl_name="int40u", byte_count=5, is_signed=False),
    "int48s": BasicInteger(idl_name="int48s", byte_count=6, is_signed=True),
    "int48u": BasicInteger(idl_name="int48u", byte_count=6, is_signed=False),
    "int56s": BasicInteger(idl_name="int56s", byte_count=7, is_signed=True),
    "int56u": BasicInteger(idl_name="int56u", byte_count=7, is_signed=False),
    "int64s": BasicInteger(idl_name="int64s", byte_count=8, is_signed=True),
    "int64u": BasicInteger(idl_name="int64u", byte_count=8, is_signed=False),
    "int8s": BasicInteger(idl_name="int8s", byte_count=1, is_signed=True),
    "int8u": BasicInteger(idl_name="int8u", byte_count=1, is_signed=False),
    # Derived types
    # Specification describes them in section '7.18.2. Derived Data Types'
    "action_id": BasicInteger(idl_name="action_id", byte_count=1, is_signed=False),
    "attrib_id": BasicInteger(idl_name="attrib_id", byte_count=4, is_signed=False),
    "cluster_id": BasicInteger(idl_name="cluster_id", byte_count=4, is_signed=False),
    "command_id": BasicInteger(idl_name="command_id", byte_count=4, is_signed=False),
    "data_ver": BasicInteger(idl_name="data_ver", byte_count=4, is_signed=False),
    "date": BasicInteger(idl_name="date", byte_count=4, is_signed=False),
    "devtype_id": BasicInteger(idl_name="devtype_id", byte_count=4, is_signed=False),
    "endpoint_no": BasicInteger(idl_name="endpoint_no", byte_count=2, is_signed=False),
    "epoch_s": BasicInteger(idl_name="epoch_s", byte_count=4, is_signed=False),
    "epoch_us": BasicInteger(idl_name="epoch_us", byte_count=8, is_signed=False),
    "event_id": BasicInteger(idl_name="event_id", byte_count=4, is_signed=False),
    "event_no": BasicInteger(idl_name="event_no", byte_count=8, is_signed=False),
    "fabric_id": BasicInteger(idl_name="fabric_id", byte_count=8, is_signed=False),
    "fabric_idx": BasicInteger(idl_name="fabric_idx", byte_count=1, is_signed=False),
    "field_id": BasicInteger(idl_name="field_id", byte_count=4, is_signed=False),
    "group_id": BasicInteger(idl_name="group_id", byte_count=2, is_signed=False),
    "node_id": BasicInteger(idl_name="node_id", byte_count=8, is_signed=False),
    "percent": BasicInteger(idl_name="percent", byte_count=1, is_signed=False),
    "percent100ths": BasicInteger(idl_name="percent100ths", byte_count=2, is_signed=False),
    "status": BasicInteger(idl_name="status", byte_count=2, is_signed=False),
    "systime_us": BasicInteger(idl_name="systime_us", byte_count=8, is_signed=False),
    "tod": BasicInteger(idl_name="tod", byte_count=4, is_signed=False),
    "trans_id": BasicInteger(idl_name="trans_id", byte_count=4, is_signed=False),
    "vendor_id": BasicInteger(idl_name="vendor_id", byte_count=2, is_signed=False),
}


class TypeLookupContext:
    """
    Handles type lookups within a scope.

    Generally when looking for a struct/enum, the lookup will be first done
    at a cluster level, then at a global level.

    Example:

    ================ test.matter ==============
    enum A {}

    server cluster X {
      struct A {}
      struct B {}
    }

    server cluster Y {
      enum C {}
    }
    ===========================================

    When considering a lookup context of global (i.e. cluster is not set)
       "A" is defined as an enum (::A)
       "B" is undefined
       "C" is undefined

    When considering a lookup context of cluster X
       "A" is defined as a struct (X::A)
       "B" is defined as a struct (X::B)
       "C" is undefined

    When considering a lookup context of cluster Y
       "A" is defined as an enum (::A)
       "B" is undefined
       "C" is defined as an enum (Y::C)

    """

    def __init__(self, idl: matter_idl_types.Idl, cluster: Optional[matter_idl_types.Cluster]):
        self.idl = idl
        self.cluster = cluster

    def find_enum(self, name) -> Optional[matter_idl_types.Enum]:
        """
        Find the first enumeration matching the given name for the given
        lookup rules (searches cluster first, then global).
        """
        for e in self.all_enums:
            if e.name == name:
                return e

        return None

    def find_struct(self, name) -> Optional[matter_idl_types.Struct]:
        for s in self.all_structs:
            if s.name == name:
                return s

        return None

    def find_bitmap(self, name) -> Optional[matter_idl_types.Bitmap]:
        for s in self.all_bitmaps:
            if s.name == name:
                return s

        return None

    @property
    def all_enums(self):
        """
        All enumerations, ordered by lookup priority.

        If an enum A is defined both in the cluster and globally, this WILL
        return both instances, however it will return the cluster version first.
        """
        if self.cluster:
            for e in self.cluster.enums:
                yield e
        for e in self.idl.enums:
            yield e

    @property
    def all_bitmaps(self):
        """
        All bitmaps defined within this lookup context.

        bitmaps are only defined at cluster level. If lookup context does not
        include a cluster, the bitmal list will be empty.
        """
        if self.cluster:
            for b in self.cluster.bitmaps:
                yield b

    @property
    def all_structs(self):
        """All structs, ordered by lookup prioroty.

        If a struct A is defined both in the cluster and globally, this WILL
        return both instances, however it will return the cluster version first.
        """
        if self.cluster:
            for e in self.cluster.structs:
                yield e
        for e in self.idl.structs:
            yield e

    def is_enum_type(self, name: str):
        """
        Determine if the given type name is an enumeration.

        Handles both standard names (like enum8) as well as enumerations defined
        within the current lookup context.
        """
        if name.lower() in ["enum8", "enum16", "enum32"]:
            return True
        return any(map(lambda e: e.name == name, self.all_enums))

    def is_struct_type(self, name: str):
        """
        Determine if the given type name is type that is known to be a struct
        """
        return any(map(lambda s: s.name == name, self.all_structs))

    def is_bitmap_type(self, name: str):
        """
        Determine if the given type name is type that is known to be a bitmap.

        Handles both standard/zcl names (like bitmap32) and types defined within
        the current lookup context.
        """
        if name.lower() in ["bitmap8", "bitmap16", "bitmap24", "bitmap32", "bitmap64"]:
            return True

        return any(map(lambda s: s.name == name, self.all_bitmaps))


def ParseDataType(data_type: DataType, lookup: TypeLookupContext) -> Union[BasicInteger, BasicString, FundamentalType, IdlType]:
    """
    Given a AST data type and a lookup context, match it to a type that can be later
    be used for generation.

    AST parsing is textual, so it does not understand what "foo" means. This method
    looks up what "foo" actually means: includes basic types (e.g. bool),
    zcl types (like enums or bitmaps) and does lookups to find structs/enums/bitmaps/etc
    that are defined in the given lookup context.
    """

    lowercase_name = data_type.name.lower()

    if lowercase_name == 'boolean':
        return FundamentalType.BOOL
    if lowercase_name == 'single':
        return FundamentalType.FLOAT
    elif lowercase_name == 'double':
        return FundamentalType.DOUBLE
    elif lowercase_name in ['char_string', 'long_char_string']:
        return BasicString(idl_name=lowercase_name, is_binary=False, max_length=data_type.max_length)
    elif lowercase_name in ['octet_string', 'long_octet_string']:
        return BasicString(idl_name=lowercase_name, is_binary=True, max_length=data_type.max_length)
    elif lowercase_name in ['enum8', 'enum16', 'enum32']:
        return IdlEnumType(idl_name=lowercase_name, base_type=__CHIP_SIZED_TYPES__[lowercase_name])
    elif lowercase_name in ['bitmap8', 'bitmap16', 'bitmap24', 'bitmap32']:
        return IdlEnumType(idl_name=lowercase_name, base_type=__CHIP_SIZED_TYPES__[lowercase_name])

    int_type = __CHIP_SIZED_TYPES__.get(lowercase_name, None)
    if int_type is not None:
        return int_type

    # All fast checks done, now check against known data types
    e = lookup.find_enum(data_type.name)
    if e:
        # Valid enum found. it MUST be based on a valid data type
        return IdlEnumType(idl_name=data_type.name, base_type=__CHIP_SIZED_TYPES__[e.base_type.lower()])

    b = lookup.find_bitmap(data_type.name)
    if b:
        # Valid enum found. it MUST be based on a valid data type
        return IdlBitmapType(idl_name=data_type.name, base_type=__CHIP_SIZED_TYPES__[b.base_type.lower()])

    result = IdlType(idl_name=data_type.name, item_type=IdlItemType.UNKNOWN)
    if lookup.find_struct(data_type.name):
        result.item_type = IdlItemType.STRUCT
    else:
        logging.warn(
            "Data type %s is NOT known, but treating it as a generic IDL type." % data_type)

    return result
