#!/usr/bin/env python3
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (c) 2012, Intel Corporation.
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# DESCRIPTION
# 'yocto-bsp' is the Yocto BSP Tool that helps users create a new
# Yocto BSP.  Invoking it without any arguments will display help
# screens for the 'yocto-bsp' command and list the available
# 'yocto-bsp' subcommands.  Invoking a subcommand without any
# arguments will likewise display help screens for the specified
# subcommand.  Please use that interface for detailed help.
#
# AUTHORS
# Tom Zanussi <tom.zanussi (at] intel.com>
#

import os
import sys
import argparse
import logging

scripts_path = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, scripts_path + '/lib')
import argparse_oe

from bsp.help import *
from bsp.engine import *


def do_create_bsp(args):
    """
    Command-line handling for BSP creation.  The real work is done by
    bsp.engine.yocto_bsp_create()
    """
    if args.outdir:
        bsp_output_dir = args.outdir
    else:
        bsp_output_dir = "meta-" + args.bspname

    if args.git_check and not args.properties_file:
        print("Checking basic git connectivity...")
        if not verify_git_repo(GIT_CHECK_URI):
            print("Couldn't verify git connectivity, exiting\n")
            print("Details: couldn't access %s" % GIT_CHECK_URI)
            print("         (this most likely indicates a network connectivity problem or")
            print("         a misconfigured git intallation)")
            sys.exit(1)
        else:
            print("Done.\n")

    yocto_bsp_create(args.bspname, args.karch, scripts_path, bsp_output_dir, args.codedump, args.properties_file)


def do_list_bsp(args):
    """
    Command-line handling for listing available BSP properties and
    values.  The real work is done by bsp.engine.yocto_bsp_list()
    """
    yocto_bsp_list(args, scripts_path)

def do_help_bsp(args):
    """
    Command-line help tool
    """
    help_text = command_help.get(args.subcommand)
    pager = subprocess.Popen('less', stdin=subprocess.PIPE)
    pager.communicate(bytes(help_text,'UTF-8'))

command_help = {
    "create": yocto_bsp_create_help,
    "list":  yocto_bsp_list_help
}


def start_logging(loglevel):
    logging.basicConfig(filename = 'yocto-bsp.log', filemode = 'w', level=loglevel)


def main():
    parser = argparse_oe.ArgumentParser(description='Create a customized Yocto BSP layer.',
                      epilog="See '%(prog)s help <subcommand>' for more information on a specific command.")

    parser.add_argument("-D", "--debug", action = "store_true",
                      default = False, help = "output debug information")
    subparsers = parser.add_subparsers(title='subcommands', metavar='<subcommand>')
    subparsers.required = True

    create_parser = subparsers.add_parser('create', help='Create a new Yocto BSP',
                                          description='Create a new Yocto BSP')
    create_parser.add_argument('bspname', metavar='bsp-name', help='name for the new BSP')
    create_parser.add_argument('karch', help='kernel architecture')
    create_parser.add_argument("-o", "--outdir", help = "name of BSP dir to create")
    create_parser.add_argument("-i", "--infile", dest = "properties_file",
                      help = "name of file containing the values for BSP properties as a JSON file")
    create_parser.add_argument("-c", "--codedump", action = "store_true", default = False,
                      help = "dump the generated code to bspgen.out")
    create_parser.add_argument("-s", "--skip-git-check", dest = "git_check", action = "store_false",
                      default = True, help = "skip the git connectivity check")
    create_parser.set_defaults(func=do_create_bsp)


    list_parser = subparsers.add_parser('list', help='List available values for options and BSP properties')
    list_parser.add_argument('karch', help='kernel architecture')
    prop_group = list_parser.add_mutually_exclusive_group()
    prop_group.add_argument("--properties", action = "store_true", default = False,
                      help = "list all properties for the kernel architecture")
    prop_group.add_argument("--property", help = "list available values for the property")
    list_parser.add_argument("-o", "--outfile", dest = "properties_file",
                      help = "dump the possible values for BSP properties to a JSON file")

    list_parser.set_defaults(func=do_list_bsp)

    help_parser = subparsers.add_parser('help',
                      description='This command displays detailed help for the specified subcommand.')
    help_parser.add_argument('subcommand', nargs='?')
    help_parser.set_defaults(func=do_help_bsp)

    args = parser.parse_args()

    loglevel = logging.INFO
    if args.debug:
        loglevel = logging.DEBUG
    start_logging(loglevel)

    if args._subparser_name == "list":
        if not args.karch == "karch" and not args.properties and not args.property:
            print ("yocto-bsp list: error: one of the arguments --properties --property is required")
            list_parser.print_help()

    if args._subparser_name == "help":
        if not args.subcommand:
            parser.print_help()
            return 0
        elif not command_help.get(args.subcommand):
            print ("yocto-bsp help: No manual entry for %s" % args.subcommand)
            return 1

    return args.func(args)

if __name__ == "__main__":
    try:
        ret = main()
    except Exception:
        ret = 1
        import traceback
        traceback.print_exc()
    sys.exit(ret)
