#
# Copyright 2017 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.
#
from uuid import uuid4
import structlog
from voltha.protos.common_pb2 import ConnectStatus, OperStatus
from voltha.protos.logical_device_pb2 import LogicalDevice, LogicalPort
from voltha.protos.openflow_13_pb2 import ofp_desc, ofp_switch_features, OFPC_FLOW_STATS, OFPC_TABLE_STATS, \
    OFPC_PORT_STATS, OFPC_GROUP_STATS, ofp_port, OFPPS_LIVE, OFPPF_10GB_FD, OFPPF_FIBER

log = structlog.get_logger()

def mac_str_to_tuple(mac):
    """
    Convert 'xx:xx:xx:xx:xx:xx' MAC address string to a tuple of integers.
    Example: mac_str_to_tuple('00:01:02:03:04:05') == (0, 1, 2, 3, 4, 5)
    """
    return tuple(int(d, 16) for d in mac.split(':'))

class DeviceManager(object):

    def __init__(self, device, adapter_agent):
        self.device = device
        self.adapter_agent = adapter_agent
        self.logical_device = None

    def update_device(self, pkt):

        self.device.root = True
        self.device.vendor = 'Celestica Inc.'
        self.device.model = 'Ruby'
        self.device.hardware_version = \
            '{}.{}'.format(hex(pkt.major_hardware_version),
                           pkt.minor_hardware_version)
        self.device.firmware_version = '{}.{}.{}'.format(pkt.major_firmware_version,
                                                         pkt.minor_firmware_version,
                                                         pkt.build_firmware_version)
        self.device.software_version = '0.0.1'
        self.device.serial_number = self.device.mac_address
        self.device.connect_status = ConnectStatus.REACHABLE
        self.adapter_agent.update_device(self.device)

    def create_logical_device(self):
        log.info('create-logical-device')
        # then shortly after we create the logical device with one port
        # that will correspond to the NNI port
        ld = LogicalDevice(
            desc=ofp_desc(
                mfr_desc=self.device.vendor,
                hw_desc=self.device.hardware_version,
                sw_desc=self.device.firmware_version,
                serial_num=uuid4().hex,
                dp_desc='n/a'
            ),
            switch_features=ofp_switch_features(
                n_buffers=256,  # TODO fake for now
                n_tables=2,  # TODO ditto
                capabilities=(  # TODO and ditto
                    OFPC_FLOW_STATS
                    | OFPC_TABLE_STATS
                    | OFPC_PORT_STATS
                    | OFPC_GROUP_STATS
                )
            ),
            root_device_id=self.device.id
        )

        self.logical_device = self.adapter_agent.create_logical_device(ld)

    def add_port(self, port):
        self.adapter_agent.add_port(self.device.id, port)

        cap = OFPPF_10GB_FD | OFPPF_FIBER
        logical_port = LogicalPort(
            id='uni',
            ofp_port=ofp_port(
                port_no=port.port_no,
                hw_addr=mac_str_to_tuple(self.device.mac_address),
                name='{}-{}'.format(port.label, port.port_no),
                config=0,
                state=OFPPS_LIVE,
                curr=cap,
                advertised=cap,
                peer=cap,
                curr_speed=OFPPF_10GB_FD,
                max_speed=OFPPF_10GB_FD
            )
        )
        self.adapter_agent.add_logical_port(self.logical_device.id,
                                            logical_port)

    def activate(self):
        self.device.parent_id = self.logical_device.id
        self.device.oper_status = OperStatus.ACTIVE
        self.adapter_agent.update_device(self.device)
