#!/usr/bin/env python3
#
# Copyright (c) 2019, Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0

'''Tool for parsing a list of projects to determine if they are Zephyr
projects. If no projects are given then the output from `west list` will be
used as project list.

Include file is generated for Kconfig using --kconfig-out.
A <name>:<path> text file is generated for use with CMake using --cmake-out.
'''

import argparse
import os
import sys
import yaml
import pykwalify.core
import subprocess
import re
from pathlib import PurePath

METADATA_SCHEMA = '''
## A pykwalify schema for basic validation of the structure of a
## metadata YAML file.
##
# The zephyr/module.yml file is a simple list of key value pairs to be used by
# the build system.
type: map
mapping:
  build:
    required: true
    type: map
    mapping:
      cmake:
        required: false
        type: str
      kconfig:
        required: false
        type: str
'''

schema = yaml.safe_load(METADATA_SCHEMA)


def validate_setting(setting, module_path, filename=None):
    if setting is not None:
        if filename is not None:
            checkfile = os.path.join(module_path, setting, filename)
        else:
            checkfile = os.path.join(module_path, setting)
        if not os.path.isfile(checkfile):
            return False
    return True


def process_module(module, cmake_out=None, kconfig_out=None):
    cmake_setting = None
    kconfig_setting = None

    module_yml = os.path.join(module, 'zephyr/module.yml')
    if os.path.isfile(module_yml):
        with open(module_yml, 'r') as f:
            meta = yaml.safe_load(f.read())

        try:
            pykwalify.core.Core(source_data=meta, schema_data=schema)\
                .validate()
        except pykwalify.errors.SchemaError as e:
            print('ERROR: Malformed "build" section in file: {}\n{}'
                  .format(module_yml, e), file=sys.stderr)
            sys.exit(1)

        section = meta.get('build', dict())
        cmake_setting = section.get('cmake', None)
        if not validate_setting(cmake_setting, module, 'CMakeLists.txt'):
            print('ERROR: "cmake" key in {} has folder value "{}" which '
                  'does not contain a CMakeLists.txt file.'
                  .format(module_yml, cmake_setting), file=sys.stderr)
            sys.exit(1)

        kconfig_setting = section.get('kconfig', None)
        if not validate_setting(kconfig_setting, module):
            print('ERROR: "kconfig" key in {} has value "{}" which does not '
                  'point to a valid Kconfig file.'
                  .format(module_yml, kconfig_setting), file=sys.stderr)
            sys.exit(1)

    cmake_path = os.path.join(module, cmake_setting or 'zephyr')
    cmake_file = os.path.join(cmake_path, 'CMakeLists.txt')
    if os.path.isfile(cmake_file) and cmake_out is not None:
        cmake_out.write('\"{}\":\"{}\"\n'.format(os.path.basename(module),
                                                 os.path.abspath(cmake_path)))

    kconfig_file = os.path.join(module, kconfig_setting or 'zephyr/Kconfig')
    if os.path.isfile(kconfig_file) and kconfig_out is not None:
        kconfig_out.write('osource "{}"\n\n'
                          .format(PurePath(
                              os.path.abspath(kconfig_file)).as_posix()))


def main():
    kconfig_out_file = None
    cmake_out_file = None

    parser = argparse.ArgumentParser(description='''
    Process a list of projects and create Kconfig / CMake include files for
    projects which are also a Zephyr module''')

    parser.add_argument('--kconfig-out',
                        help='File to write with resulting KConfig import'
                             'statements.')
    parser.add_argument('--cmake-out',
                        help='File to write with resulting <name>:<path>'
                             'values to use for including in CMake')
    parser.add_argument('-m', '--modules', nargs='+',
                        help='List of modules to parse instead of using `west'
                             'list`')
    parser.add_argument('-x', '--extra-modules', nargs='+',
                        help='List of extra modules to parse')
    args = parser.parse_args()

    if args.modules is None:
        p = subprocess.Popen(['west', 'list', '--format={posixpath}'],
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        out, err = p.communicate()
        if p.returncode == 0:
            projects = out.decode(sys.getdefaultencoding()).splitlines()
        elif re.match(r'Error: .* is not in a west installation\..*',
                      err.decode(sys.getdefaultencoding())):
            # Only accept the error from bootstrapper in the event we are
            # outside a west managed project.
            projects = []
        else:
            # A real error occurred, raise an exception
            raise subprocess.CalledProcessError(cmd=p.args,
                                                returncode=p.returncode)
    else:
        projects = args.modules

    if args.extra_modules is not None:
        projects += args.extra_modules

    if args.kconfig_out:
        kconfig_out_file = open(args.kconfig_out, 'w')

    if args.cmake_out:
        cmake_out_file = open(args.cmake_out, 'w')

    try:
        for project in projects:
            # Avoid including Zephyr base project as module.
            if project != os.environ.get('ZEPHYR_BASE'):
                process_module(project, cmake_out_file, kconfig_out_file)
    finally:
        if args.kconfig_out:
            kconfig_out_file.close()
        if args.cmake_out:
            cmake_out_file.close()


if __name__ == "__main__":
    main()
