# 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 logging
import enum

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

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


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
