# 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-12
        # 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)
        
        # Delete the downstream flow
        self.del_flow(datapath, 10001)
        # Then delete the upstream flow
        self.del_flow(datapath, 10000)

    @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()
                   
