#
# Copyright 2018 the original author or 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.
#

"""
Resource Manager will be unique for each OLT device.

It exposes APIs to create/free alloc_ids/onu_ids/gemport_ids. Resource Manager
uses a KV store in backend to ensure resiliency of the data.
"""
from bitstring import BitArray
import json
from pyvoltha.adapters.common.pon_resource_manager.resource_manager import PONResourceManager
import adtranolt_platform as platform


class AdtranPONResourceManager(PONResourceManager):
    """Implements APIs to initialize/allocate/release alloc/gemport/onu IDs."""

    # Constants for internal usage.
    ONU_MAP = 'onu_map'

    def init_device_resource_pool(self):
        """
        Initialize resource pool for all PON ports.
        """
        for pon_id in self.intf_ids:
            self.init_resource_id_pool(
                pon_intf_id=pon_id,
                resource_type=PONResourceManager.ONU_ID,
                start_idx=self.pon_resource_ranges[PONResourceManager.ONU_ID_START_IDX],
                end_idx=self.pon_resource_ranges[PONResourceManager.ONU_ID_END_IDX])

            alloc_id_map = dict()
            for onu_id in range(platform.MAX_ONUS_PER_PON):
                alloc_id_map[onu_id] = [platform.mk_alloc_id(pon_id, onu_id, idx)
                                        for idx in xrange(platform.MAX_TCONTS_PER_ONU)]

            self.init_resource_id_pool(pon_intf_id=pon_id,
                                       resource_type=PONResourceManager.ALLOC_ID,
                                       resource_map=alloc_id_map)

            self.init_resource_id_pool(
                pon_intf_id=pon_id,
                resource_type=PONResourceManager.GEMPORT_ID,
                start_idx=self.pon_resource_ranges[PONResourceManager.GEMPORT_ID_START_IDX],
                end_idx=self.pon_resource_ranges[PONResourceManager.GEMPORT_ID_END_IDX])

    def clear_device_resource_pool(self):
        """
        Clear resource pool of all PON ports.
        """
        for pon_id in self.intf_ids:
            self.clear_resource_id_pool(pon_intf_id=pon_id,
                                        resource_type=PONResourceManager.ONU_ID)

            self.clear_resource_id_pool(
                pon_intf_id=pon_id,
                resource_type=PONResourceManager.ALLOC_ID,
            )

            self.clear_resource_id_pool(
                pon_intf_id=pon_id,
                resource_type=PONResourceManager.GEMPORT_ID,
            )
            self.clear_resource_id_pool(
                pon_intf_id=pon_id,
                resource_type=PONResourceManager.FLOW_ID,
            )

    def init_resource_id_pool(self, pon_intf_id, resource_type, start_idx=None,
                              end_idx=None, resource_map=None):
        """
        Initialize Resource ID pool for a given Resource Type on a given PON Port

        :param pon_intf_id: OLT PON interface id
        :param resource_type: String to identify type of resource
        :param start_idx: start index for onu id pool
        :param end_idx: end index for onu id pool
        :param resource_map: (dict) Resource map if per-ONU specific
        :return boolean: True if resource id pool initialized else false
        """
        status = False
        path = self._get_path(pon_intf_id, resource_type)
        if path is None:
            return status

        try:
            # In case of adapter reboot and reconciliation resource in kv store
            # checked for its presence if not kv store update happens
            resource = self._get_resource(path)

            if resource is not None:
                self._log.info("Resource-already-present-in-store", path=path)
                status = True

            else:
                if resource_map is None:
                    resource = self._format_resource(pon_intf_id, start_idx, end_idx)
                    self._log.info("Resource-initialized", path=path)

                else:
                    resource = self._format_map_resource(pon_intf_id, resource_map)

                # Add resource as json in kv store.
                status = self._kv_store.update_to_kv_store(path, resource)

        except Exception as e:
            self._log.exception("error-initializing-resource-pool", e=e)

        return status

    def _generate_next_id(self, resource, onu_id=None):
        """
        Generate unique id having OFFSET as start index.

        :param resource: resource used to generate ID
        :return int: generated id
        """
        if onu_id is not None:
            resource = resource[AdtranPONResourceManager.ONU_MAP][str(onu_id)]

        pos = resource[PONResourceManager.POOL].find('0b0')
        resource[PONResourceManager.POOL].set(1, pos)
        return pos[0] + resource[PONResourceManager.START_IDX]

    def _release_id(self, resource, unique_id, onu_id=None):
        """
        Release unique id having OFFSET as start index.

        :param resource: resource used to release ID
        :param unique_id: id need to be released
        :param onu_id: ONU ID if unique per ONU
        """
        if onu_id is not None:
            resource = resource[AdtranPONResourceManager.ONU_MAP][str(onu_id)]

        pos = ((int(unique_id)) - resource[PONResourceManager.START_IDX])
        resource[PONResourceManager.POOL].set(0, pos)

    def get_resource_id(self, pon_intf_id, resource_type, onu_id=None, num_of_id=1):
        """
        Create alloc/gemport/onu id for given OLT PON interface.

        :param pon_intf_id: OLT PON interface id
        :param resource_type: String to identify type of resource
        :param num_of_id: required number of ids
        :param onu_id: ONU ID if unique per ONU  (Used for Alloc IDs)
        :return list/int/None: list, int or None if resource type is
                               alloc_id/gemport_id, onu_id or invalid type
                               respectively
        """
        result = None

        if num_of_id < 1:
            self._log.error("invalid-num-of-resources-requested")
            return result

        path = self._get_path(pon_intf_id, resource_type)
        if path is None:
            return result

        try:
            resource = self._get_resource(path, onu_id)
            if resource is not None and \
                    (resource_type == PONResourceManager.ONU_ID or
                     resource_type == PONResourceManager.FLOW_ID):
                result = self._generate_next_id(resource)

            elif resource is not None and \
                    resource_type == PONResourceManager.GEMPORT_ID:
                if num_of_id == 1:
                    result = self._generate_next_id(resource)
                else:
                    result = [self._generate_next_id(resource) for _ in range(num_of_id)]

            elif resource is not None and \
                    resource_type == PONResourceManager.ALLOC_ID:
                if num_of_id == 1:
                    result = self._generate_next_id(resource, onu_id)
                else:
                    result = [self._generate_next_id(resource, onu_id) for _ in range(num_of_id)]
            else:
                raise Exception("get-resource-failed")

            self._log.debug("Get-" + resource_type + "-success", result=result,
                            path=path)
            # Update resource in kv store
            self._update_resource(path, resource, onu_id=onu_id)

        except Exception as e:
            self._log.exception("Get-" + resource_type + "-id-failed",
                                path=path, e=e)
        return result

    def free_resource_id(self, pon_intf_id, resource_type, release_content, onu_id=None):
        """
        Release alloc/gemport/onu id for given OLT PON interface.

        :param pon_intf_id: OLT PON interface id
        :param resource_type: String to identify type of resource
        :param release_content: required number of ids
        :param onu_id: ONU ID if unique per ONU
        :return boolean: True if all IDs in given release_content released
                         else False
        """
        status = False

        path = self._get_path(pon_intf_id, resource_type)
        if path is None:
            return status

        try:
            resource = self._get_resource(path, onu_id=onu_id)
            if resource is None:
                raise Exception("get-resource-for-free-failed")

            if resource_type == PONResourceManager.ONU_ID:
                self._release_id(resource, release_content)

            elif resource_type == PONResourceManager.ALLOC_ID:
                for content in release_content:
                    self._release_id(resource, content)

            elif resource_type == PONResourceManager.GEMPORT_ID:
                for content in release_content:
                    self._release_id(resource, content, onu_id)
            else:
                raise Exception("get-resource-for-free-failed")

            self._log.debug("Free-" + resource_type + "-success", path=path)

            # Update resource in kv store
            status = self._update_resource(path, resource, onu_id=onu_id)

        except Exception as e:
            self._log.exception("Free-" + resource_type + "-failed",
                                path=path, e=e)
        return status

    def _update_resource(self, path, resource, onu_id=None):
        """
        Update resource in resource kv store.

        :param path: path to update resource
        :param resource: resource need to be updated
        :return boolean: True if resource updated in kv store else False
        """
        if 'alloc_id' in path.lower():
            assert onu_id is not None
            poolResource = resource[AdtranPONResourceManager.ONU_MAP][str(onu_id)]
            poolResource[PONResourceManager.POOL] = \
                poolResource[PONResourceManager.POOL].bin
        else:
            resource[PONResourceManager.POOL] = \
                resource[PONResourceManager.POOL].bin

        return self._kv_store.update_to_kv_store(path, json.dumps(resource))

    def _get_resource(self, path, onu_id=None):
        """
        Get resource from kv store.

        :param path: path to get resource
        :return: resource if resource present in kv store else None
        """
        # get resource from kv store
        result = self._kv_store.get_from_kv_store(path)
        if result is None:
            return result

        self._log.info("dumping-resource", result=result)
        resource = result

        if resource is not None:
            # decode resource fetched from backend store to dictionary
            resource = json.loads(resource)

            if 'alloc_id' in path.lower():
                assert onu_id is not None
                poolResource = resource[AdtranPONResourceManager.ONU_MAP][str(onu_id)]
                poolResource[PONResourceManager.POOL] = \
                    BitArray('0b' + poolResource[PONResourceManager.POOL])
            else:
                # resource pool in backend store stored as binary string whereas to
                # access the pool to generate/release IDs it need to be converted
                # as BitArray
                resource[PONResourceManager.POOL] = \
                    BitArray('0b' + resource[PONResourceManager.POOL])

        return resource

    def _format_resource(self, pon_intf_id, start_idx, end_idx):
        """
        Format resource as json.

        :param pon_intf_id: OLT PON interface id
        :param start_idx: start index for id pool
        :param end_idx: end index for id pool
        :return dictionary: resource formatted as dictionary
        """
        # Format resource as json to be stored in backend store
        resource = dict()
        resource[PONResourceManager.PON_INTF_ID] = pon_intf_id
        resource[PONResourceManager.START_IDX] = start_idx
        resource[PONResourceManager.END_IDX] = end_idx

        # resource pool stored in backend store as binary string
        resource[PONResourceManager.POOL] = BitArray(end_idx-start_idx).bin

        return json.dumps(resource)

    def _format_map_resource(self, pon_intf_id, resource_map):
        """
        Format resource as json.
        # TODO: Refactor the resource BitArray to be just a list of the resources.
        #       This is used to store available alloc-id's on a per-onu/pon basis
        #       which in BitArray string form, is a 768 byte string for just 4 possible
        #       alloc-IDs.  This equates to 1.57 MB of storage when you take into
        #       account 128 ONUs and 16 PONs pre-provisioneed
        :param pon_intf_id: OLT PON interface id
        :param resource_map: (dict) ONU ID -> Scattered list of IDs
        :return dictionary: resource formatted as dictionary
        """
        # Format resource as json to be stored in backend store
        resource = dict()
        resource[PONResourceManager.PON_INTF_ID] = pon_intf_id

        onu_dict = dict()
        for onu_id, resources in resource_map.items():
            start_idx = min(resources)
            end_idx = max(resources) + 1

            onu_dict[onu_id] = {
                PONResourceManager.START_IDX: start_idx,
                PONResourceManager.END_IDX: end_idx,
            }
            # Set non-allowed values as taken
            resource_map = BitArray(end_idx - start_idx)
            not_available = {pos for pos in xrange(end_idx-start_idx)
                             if pos + start_idx not in resources}
            resource_map.set(True, not_available)
            onu_dict[onu_id][PONResourceManager.POOL] = resource_map.bin

        resource[AdtranPONResourceManager.ONU_MAP] = onu_dict
        return json.dumps(resource)
