# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation.
#
# 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

from ryu.base import app_manager
from time import sleep
from ryu.controller import ofp_event
from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_3
from ryu.lib.packet import packet
from ryu.lib.packet import ethernet
from ryu.lib import addrconv

LOG = logging.getLogger('ryu.app.pon_topology')

class PonTopology13(app_manager.RyuApp):
    OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]

    def __init__(self, *args, **kwargs):
        super(PonTopology13, self).__init__(*args, **kwargs)
        self.mac_to_port = {}

    @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def switch_features_handler(self, ev):
        datapath = ev.msg.datapath

        # This does nothing if flows have not been previously configured in the OF agent
        self.del_all_flows(datapath)

        # Configure the flows (VID 100)
        #
        # Ports 1-128 are implicitly mapped to UNI-0 on ONU 1->128
        # Ports 129 and above are implicitly mapped to OLT NNI-0 and above
        self.add_vid_flow(datapath,10000, 1, 129, 100, 0)
        self.add_vid_flow(datapath,10001, 129, 1, 100, 0)

        sleep(1)
        self.send_barrier(datapath)

        sleep(5)
        
        self.del_all_flows(datapath)

    @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER)
    def port_status_handler(self, ev):
        LOG.debug('port_status_handler port id: %d', ev.msg.desc.port_no)

    def add_meter(self, datapath, meter_id, rate):
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        band = parser.OFPMeterBandDrop(burst_size=0, rate=rate)
        mod = parser.OFPMeterMod(datapath=datapath,command=ofproto.OFPMC_ADD, flags=ofproto.OFPMF_KBPS, meter_id=meter_id, bands=[band])
        LOG.info("add_meter: meter_id=%d, rate=%d KBPS")
        datapath.send_msg(mod)

    def add_vid_flow(self, datapath, cookie, src_port, dst_port, vid, meter_id):
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        actions = [parser.OFPActionOutput(dst_port)]
        if meter_id != 0:
            inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions), parser.OFPInstructionMeter(meter_id)]
        else:
            inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]

        # NOTE: 0x1000 is OR'd into the vid to set the OFPVID_PRESENT flag in the OpenFlow FLOW_MOD (OFPFC_ADD) 
        # message match field.
        match = parser.OFPMatch(in_port=src_port, vlan_vid=(vid | 0x1000))
        mod = parser.OFPFlowMod(datapath=datapath,
                                cookie=cookie, 
                                cookie_mask=32767, 
                                priority=0, 
                                match=match, 
                                instructions=inst)
        LOG.info("add_vid_flow: src_port=%d dst_port=%d vid=%d meter=%d cookie=%d", 
                 src_port, dst_port, vid, meter_id, cookie)
        datapath.send_msg(mod)

    def del_flow(self, datapath, cookie):
        LOG.info("del_flow: cookie=%d", cookie)
        self._del_flow(datapath, cookie, 32767)

    def del_all_flows(self, datapath):
        LOG.info("del_all_flows")
        # Cookie 0 (argument 2) tells the OF agent to delete all configured flows
        self._del_flow(datapath, 0, 0)

    def _del_flow(self, datapath, cookie, mask):
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
 
        mod = parser.OFPFlowMod(
            datapath=datapath, match=None, cookie=cookie, cookie_mask=mask,
            command=ofproto.OFPFC_DELETE)
        datapath.send_msg(mod)

    def send_barrier(self, datapath):
        LOG.info("send_barrier")
        datapath.send_barrier()
                   
