#!/usr/bin/env python
# Copyright (c) 2015 Pavel Novy. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import sys
import os
import argparse
from importlib import import_module

sys.path.insert(0, os.path.join(
        os.path.dirname(os.path.abspath(__file__)), '..', 'lib', 'rfl-gen'))

import rfl.proto


def Main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-g', '--generator', required=True,
                        help='Generator module')
    parser.add_argument('-i', '--inputs', nargs='+',
                        help='Input files')
    parser.add_argument('-o', '--output-dir',
                        help='Output directory')
    parser.add_argument('-p', '--print-files', action='store_true',
                        help='Print output files')
    parser.add_argument('-m', '--merge', action='store_true',
                        help='Merge input files')
    parser.add_argument('--pkg-name',
                        help='Package Name')
    parser.add_argument('--pkg-version',
                        help='Package Version')
    parser.add_argument('--plugin', action='store_true',
                        help='Generate plugin')
    args = parser.parse_args()

    generator_module_name = os.path.basename(args.generator)
    if os.path.isabs(args.generator):
        generator_path = os.path.dirname(args.generator)
    else:
        generator_path = os.path.abspath(os.path.dirname(args.generator))

    sys.path.append(generator_path)
    generator_module = None
    try:
        generator_module = import_module(generator_module_name)
    except ImportError as e:
        print e, generator_path, generator_module_name
        return 1

    if args.merge:
        output_file = os.path.join(args.output_dir, args.pkg_name + '.rfl')
        if args.print_files:
            print output_file
            return 0
        pkg = rfl.proto.Package()
        for proto in args.inputs:
            pb = open(proto, 'rb').read()
            input = rfl.proto.Package.FromString(pb[4:])
            if not pkg.name or pkg.name == input.name:
                pkg.MergeFrom(input)
            else:
                print 'Package names does not match', input.name, pkg.name
                return 1
        out_rfl = open(output_file, 'wb')
        out_rfl.write(b'RFL')
        out_rfl.write(b'\x01')
        out_rfl.write(pkg.SerializeToString())
        out_rfl.close()
        return 0

    pkg = None
    if not args.print_files:
        if len(args.inputs) > 1:
            pkg = rfl.proto.Package()
            for proto in args.inputs:
                pb = open(proto, 'rb').read()
                input = rfl.proto.Package.FromString(pb[4:])
                if not pkg.name or pkg.name == input.name:
                    pkg.MergeFrom(input)
                else:
                    print 'Package names does not match', input.name, pkg.name
                    return 1
        else:
            pb = open(args.inputs[0], 'rb').read()
            pkg = rfl.proto.Package.FromString(pb[4:])

    with rfl.generator.CreateContext(generator_module.Factory, args) as ctx:
        generator = ctx.CreateGenerator()
        if not args.print_files:
            package = ctx.CreatePackage(pkg)
            generator.Generate(package)
            return 0
        else:
            outs = generator.GetOutputFiles(args.pkg_name, args.pkg_version,
                                            args.inputs)
            for out in outs:
                print out
            return 0

    return 0


if __name__ == '__main__':
    sys.exit(Main())
