# 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)
        
        # Add a meter (500 Kbps rate limit) with an ID of 11
        self.add_meter(datapath, 11, 500)
 
        # Configure the flows  (VID 100) 
        # Note: the downstream flow has a meter ID reference
        #
        # Ports 1-128 are implicitly mapped to UNI-0 on ONUs 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, 11)

        sleep(1)
        self.send_barrier(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):
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
 
        mod = parser.OFPFlowMod(
            datapath=datapath, match=None, cookie=cookie, cookie_mask=32767,
            command=ofproto.OFPFC_DELETE)
        LOG.info("del_flow: cookie=%d", cookie)
        datapath.send_msg(mod)

    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()
                   



                   
