#
#    Copyright (c) 2021 Project CHIP Authors
#    All rights reserved.
#
#    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.
#

# Needed to use types in type hints before they are fully defined.
from __future__ import annotations

import logging
from typing import List

from chip import CertificateAuthority, ChipDeviceCtrl
from chip.crypto import p256keypair
from chip.native import GetLibraryHandle


class FabricAdmin:
    ''' Administers a fabric associated with a unique FabricID under a given CertificateAuthority
        instance.
    '''
    @classmethod
    def _Handle(cls):
        return GetLibraryHandle()

    @classmethod
    def logger(cls):
        return logging.getLogger('FabricAdmin')

    def __init__(self, certificateAuthority: CertificateAuthority.CertificateAuthority, vendorId: int, fabricId: int = 1):
        ''' Initializes the object.

            certificateAuthority:       CertificateAuthority instance that will be used to vend NOCs for both
                                        DeviceControllers and commissionable nodes on this fabric.
            vendorId:                   Valid operational Vendor ID associated with this fabric.
            fabricId:                   Fabric ID to be associated with this fabric.
        '''
        self._handle = GetLibraryHandle()

        if (vendorId is None or vendorId == 0):
            raise ValueError(
                f"Invalid VendorID ({vendorId}) provided!")

        if (fabricId is None or fabricId == 0):
            raise ValueError(
                f"Invalid FabricId ({fabricId}) provided!")

        self._vendorId = vendorId
        self._fabricId = fabricId
        self._certificateAuthority = certificateAuthority

        self.logger().warning(f"New FabricAdmin: FabricId: 0x{self._fabricId:016X}, VendorId = 0x{self.vendorId:04X}")

        self._isActive = True
        self._activeControllers = []

    def NewController(self, nodeId: int = None, paaTrustStorePath: str = "",
                      useTestCommissioner: bool = False, catTags: List[int] = [], keypair: p256keypair.P256Keypair = None):
        ''' Create a new chip.ChipDeviceCtrl.ChipDeviceController instance on this fabric.

            When vending ChipDeviceController instances on a given fabric, each controller instance
            is associated with a unique fabric index local to the running process. In the underlying FabricTable, each FabricInfo
            instance can be treated as unique identities that can collide on the same logical fabric.

            nodeId:         NodeID to be assigned to the controller. Automatically allocates one starting from 112233 if one
                            is not provided.

            paaTrustStorePath:      Path to the PAA trust store. If one isn't provided, a suitable default is selected.
            useTestCommissioner:    If a test commmisioner is to be created.
            catTags:			    A list of 32-bit CAT tags that will added to the NOC generated for this controller.
        '''
        if (not (self._isActive)):
            raise RuntimeError(
                "FabricAdmin object was previously shutdown and is no longer valid!")

        nodeIdList = [controller.nodeId for controller in self._activeControllers if controller.isActive]
        if (nodeId is None):
            if (len(nodeIdList) != 0):
                nodeId = max(nodeIdList) + 1
            else:
                nodeId = 112233
        else:
            if (nodeId in nodeIdList):
                raise RuntimeError(f"Provided NodeId {nodeId} collides with an existing controller instance!")

        self.logger().warning(
            f"Allocating new controller with CaIndex: {self._certificateAuthority.caIndex}, "
            f"FabricId: 0x{self._fabricId:016X}, NodeId: 0x{nodeId:016X}, CatTags: {catTags}")

        controller = ChipDeviceCtrl.ChipDeviceController(
            opCredsContext=self._certificateAuthority.GetOpCredsContext(),
            fabricId=self._fabricId,
            nodeId=nodeId,
            adminVendorId=self._vendorId,
            paaTrustStorePath=paaTrustStorePath,
            useTestCommissioner=useTestCommissioner,
            fabricAdmin=self,
            catTags=catTags,
            keypair=keypair)

        self._activeControllers.append(controller)
        return controller

    def Shutdown(self):
        ''' Shutdown all active controllers on the fabric before shutting down the fabric itself.

            You cannot interact with this object there-after.
        '''
        if (self._isActive):
            for controller in self._activeControllers:
                controller.Shutdown()

            self._isActive = False

    def __del__(self):
        self.Shutdown()

    @property
    def vendorId(self) -> int:
        return self._vendorId

    @property
    def fabricId(self) -> int:
        return self._fabricId

    @property
    def caIndex(self) -> int:
        return self._certificateAuthority.caIndex

    @property
    def certificateAuthority(self) -> CertificateAuthority.CertificateAuthority:
        return self._certificateAuthority
