#!/usr/bin/env python2.7
# -*- utf-8 -*-
import argparse
import google.protobuf.text_format as tf
import re
from p4.config.v1 import p4info_pb2

copyright = '''/*
 * Copyright 2017-present Open Networking Foundation
 *
 * 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.
 */
'''

imports = '''
import org.onosproject.net.pi.model.PiActionId;
import org.onosproject.net.pi.model.PiActionParamId;
import org.onosproject.net.pi.model.PiActionProfileId;
import org.onosproject.net.pi.model.PiMeterId;
import org.onosproject.net.pi.model.PiPacketMetadataId;
import org.onosproject.net.pi.model.PiCounterId;
import org.onosproject.net.pi.model.PiMatchFieldId;
import org.onosproject.net.pi.model.PiTableId;'''

PKG_FMT = 'package org.onosproject.pipelines.%s.impl.behaviour;'

CLASS_OPEN = 'public final class %s {'
CLASS_CLOSE = '}'

DEFAULT_CONSTRUCTOR = '''
    // hide default constructor
    private %s() {
    }
'''

CONST_FMT = '    public static final %s %s = %s;'
SHORT_CONST_FMT ='''    public static final %s %s =
            %s;'''
JAVA_STR = 'String'
EMPTY_STR = ''
JAVA_DOC_FMT = '''/**
 * Constants for %s pipeline.
 */'''


PI_HF_FIELD_ID = 'PiMatchFieldId'
PI_HF_FIELD_ID_CST = 'PiMatchFieldId.of("%s")'

PI_TBL_ID = 'PiTableId'
PI_TBL_ID_CST = 'PiTableId.of("%s")'

PI_CTR_ID = 'PiCounterId'
PI_CTR_ID_CST = 'PiCounterId.of("%s")'

PI_ACT_ID = 'PiActionId'
PI_ACT_ID_CST = 'PiActionId.of("%s")'

PI_ACT_PRM_ID = 'PiActionParamId'
PI_ACT_PRM_ID_CST = 'PiActionParamId.of("%s")'

PI_ACT_PROF_ID = 'PiActionProfileId'
PI_ACT_PROF_ID_CST = 'PiActionProfileId.of("%s")'

PI_PKT_META_ID = 'PiPacketMetadataId'
PI_PKT_META_ID_CST = 'PiPacketMetadataId.of("%s")'

PI_METER_ID = 'PiMeterId'
PI_METER_ID_CST = 'PiMeterId.of("%s")'

HF_VAR_PREFIX = 'HDR_'


class ConstantClassGenerator(object):
    headers = set()
    header_fields = set()
    tables = set()
    counters = set()
    direct_counters = set()
    actions = set()
    action_params = set()
    action_profiles = set()
    packet_metadata = set()
    meters = set()

    # https://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-snake-case
    def convert_camel_to_all_caps(self, name):
        s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
        s1 = re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).upper()
        return s1.replace('.', '_')

    def __init__(self, base_name):

        self.class_name = base_name.title() + 'Constants'
        self.package_name = PKG_FMT % (base_name, )
        self.java_doc = JAVA_DOC_FMT % (base_name, )

    def parse(self, p4info):
        for tbl in p4info.tables:
            for mf in tbl.match_fields:
                self.header_fields.add(mf.name)

            self.tables.add(tbl.preamble.name)

        for ctr in p4info.counters:
            self.counters.add(ctr.preamble.name)

        for dir_ctr in p4info.direct_counters:
            self.direct_counters.add(dir_ctr.preamble.name)

        for act in p4info.actions:
            self.actions.add(act.preamble.name)

            for param in act.params:
                self.action_params.add(param.name)

        for act_prof in p4info.action_profiles:
            self.action_profiles.add(act_prof.preamble.name)

        for cpm in p4info.controller_packet_metadata:
            for mta in cpm.metadata:
                self.packet_metadata.add(mta.name)
        for mtr in p4info.meters:
            self.meters.add(mtr.preamble.name)

    def const_line(self, name, type, constructor):
        var_name = self.convert_camel_to_all_caps(name)
        if type == PI_HF_FIELD_ID:
            var_name = HF_VAR_PREFIX + var_name
        val = constructor % (name, )

        line = CONST_FMT % (type, var_name, val)
        if len(line) > 80:
            line = SHORT_CONST_FMT % (type, var_name, val)
        return line

    def generate_java(self):
        lines = list()
        lines.append(copyright)
        lines.append(self.package_name)
        lines.append(imports)
        lines.append(self.java_doc)
        # generate the class
        lines.append(CLASS_OPEN % (self.class_name, ))
        lines.append(DEFAULT_CONSTRUCTOR % (self.class_name, ))

        if len(self.header_fields) is not 0:
            lines.append('    // Header field IDs')
        for hf in self.header_fields:
            lines.append(self.const_line(hf, PI_HF_FIELD_ID, PI_HF_FIELD_ID_CST))

        if len(self.tables) is not 0:
            lines.append('    // Table IDs')
        for tbl in self.tables:
            lines.append(self.const_line(tbl, PI_TBL_ID, PI_TBL_ID_CST))

        if len(self.counters) is not 0:
            lines.append('    // Indirect Counter IDs')
        for ctr in self.counters:
            lines.append(self.const_line(ctr, PI_CTR_ID, PI_CTR_ID_CST))

        if len(self.direct_counters) is not 0:
            lines.append('    // Direct Counter IDs')
        for dctr in self.direct_counters:
            lines.append(self.const_line(dctr, PI_CTR_ID, PI_CTR_ID_CST))

        if len(self.actions) is not 0:
            lines.append('    // Action IDs')
        for act in self.actions:
            lines.append(self.const_line(act, PI_ACT_ID, PI_ACT_ID_CST))

        if len(self.action_params) is not 0:
            lines.append('    // Action Param IDs')
        for act_prm in self.action_params:
            lines.append(self.const_line(act_prm, PI_ACT_PRM_ID, PI_ACT_PRM_ID_CST))

        if len(self.action_profiles) is not 0:
            lines.append('    // Action Profile IDs')
        for act_prof in self.action_profiles:
            lines.append(self.const_line(act_prof, PI_ACT_PROF_ID, PI_ACT_PROF_ID_CST))

        if len(self.packet_metadata) is not 0:
            lines.append('    // Packet Metadata IDs')
        for pmeta in self.packet_metadata:
            if not pmeta.startswith("_"):
                lines.append(self.const_line(pmeta, PI_PKT_META_ID, PI_PKT_META_ID_CST))

        if len(self.meters) is not 0:
            lines.append('    // Meter IDs')
        for mtr in self.meters:
            lines.append(self.const_line(mtr, PI_METER_ID, PI_METER_ID_CST))
        lines.append(CLASS_CLOSE)
        # end of class

        return '\n'.join(lines)


def main():
    parser = argparse.ArgumentParser(prog='onos-gen-p4-constants',
                                     description='ONOS P4Info to Java constant generator.')
    parser.add_argument('name', help='Name of the constant, will be used as class name')
    parser.add_argument('p4info', help='P4Info file')
    parser.add_argument('-o', '--output', help='output path', default='-')
    args = parser.parse_args()

    base_name = args.name
    file_name = args.p4info
    p4info = p4info_pb2.P4Info()
    with open(file_name, 'r') as intput_file:
        s = intput_file.read()
        tf.Merge(s, p4info)

    gen = ConstantClassGenerator(base_name)
    gen.parse(p4info)

    java_code = gen.generate_java()

    if args.output == '-':
        # std output
        print java_code
    else:
        with open(args.output, 'w') as output_file:
            output_file.write(java_code)


if __name__ == '__main__':
    main()
