# Copyright 2013, Big Switch Networks, Inc.
#
# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
# the following special exception:
#
# LOXI Exception
#
# As a special exception to the terms of the EPL, you may distribute libraries
# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
# that copyright and licensing notices generated by LoxiGen are not altered or removed
# from the LoxiGen Libraries and the notice provided below is (i) included in
# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
# documentation for the LoxiGen Libraries, if distributed in binary form.
#
# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
#
# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
# a copy of the EPL at:
#
# http://www.eclipse.org/legal/epl-v10.html
#
# 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
# EPL for the specific language governing permissions and limitations
# under the EPL.

from optparse import OptionParser

from loxi_globals import OFVersions

##@var config_default
# The default configuration dictionary for LOXI code generation
options_default = {
    "lang"               : "c",
    "version-list"       : "1.0 1.1 1.2 1.3",
    "install-dir"        : "loxi_output",
}

def lang_normalize(lang):
    """
    Normalize the representation of the language
    """
    return lang.lower()

def version_list_normalize(vlist):
    """
    Normalize the version list and return as an array
    """
    out_list = []
    # @fixme Map to OF version references
    if vlist.find(',') > 0:
        vlist = vlist.split(',')
    else:
        vlist = vlist.split()
    vlist.sort()
    for ver in vlist:
        try:
            out_list.append(OFVersions.from_string(ver))
        except KeyError:
            sys.stderr.write("Bad version input, %s" % str(ver))
            sys.exit(1)
    return out_list

def process_commandline(default_vals=options_default):
    """
    Set up the options dictionary

    @param cfg_dflt The default configuration dictionary
    @return A pair (options, args) as per parser return
    """
    parser = OptionParser(version="%prog 0.1")

    #@todo Add options via dictionary
    parser.add_option("--list-files", action="store_true", default=False,
                      help="List output files generated")
    parser.add_option("-l", "--lang", "--language",
                      default=default_vals["lang"],
                      help="Select the target language: c, python")
    parser.add_option("-i", "--install-dir",
                      default=default_vals["install-dir"],
                      help="Directory to install generated files to (default %s)" % default_vals["install-dir"])
    parser.add_option("-v", "--verbose",
                      action="store_true", default=False,
                      help="Debug output")

    parser.add_option("-V", "--version-list",
                      default=default_vals["version-list"],
                      help="Specify the versions to target as 1.0 1.1 etc")

    (options, args) = parser.parse_args()

    options.lang = lang_normalize(options.lang)
    target_version_list = version_list_normalize(options.version_list)
    target_version_list.sort()
    return (options, args, target_version_list)
