#!/usr/bin/env python3
#
# Copyright (C) 2020-2021 Savoir-faire Linux Inc.
#
# Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# 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, see <http://www.gnu.org/licenses/>.
#
# Creates packaging targets for a distribution and architecture.
# This helps reduce the length of the top Makefile.
#

# This script must unify the Plugins build for
# every project and Operational System

import os
import sys
import json
import platform
import argparse
import subprocess
import multiprocessing

IOS_DISTRIBUTION_NAME = "ios"
OSX_DISTRIBUTION_NAME = "osx"
ANDROID_DISTRIBUTION_NAME = "android"
WIN32_DISTRIBUTION_NAME = "win32"
UBUNTU_DISTRIBUTION_NAME = "ubuntu"

def parse():
    parser = argparse.ArgumentParser(description='Builds Plugins projects')
    parser.add_argument('--projects', type=str,
                        help='Select plugins to be build.')
    parser.add_argument('--distribution')
    parser.add_argument('--processor', type=str, default="GPU",
                        help='Runtime plugin CPU/GPU setting.')
    parser.add_argument('--buildOptions', default='', type=str,
                        help="Type all build optionsto pass to package.json 'defines' property.\nThis argument consider that you're using cmake.")

    dist = choose_distribution()


    args = parser.parse_args()
    args.projects = args.projects.split(',')
    args.processor = args.processor.split(',')

    if (args.distribution is not None):
        args.distribution = args.distribution.lower()
    else:
        args.distribution = dist

    if (len(args.processor) == 1):
        args.processor *= len(args.projects)

    validate_args(args)

    return args


def validate_args(parsed_args):
    """Validate the args values, exit if error is found"""

    # Filter unsupported distributions.
    supported_distros = [
        ANDROID_DISTRIBUTION_NAME, UBUNTU_DISTRIBUTION_NAME,
        WIN32_DISTRIBUTION_NAME, OSX_DISTRIBUTION_NAME
    ]

    if parsed_args.distribution not in supported_distros:
        print('Distribution \'{0}\' not supported.\nChoose one of: {1}'.format(
            parsed_args.distribution, ', '.join(supported_distros)
        ))
        sys.exit(1)

    if (len(parsed_args.processor) != len(parsed_args.projects)):
        sys.exit('Processor must be single or the same size as projects.')

    for processor in parsed_args.processor:
        if (processor not in ['GPU', 'CPU']):
            sys.exit('Processor can only be GPU or CPU.')

    if (parsed_args.buildOptions):
        parsed_args.buildOptions = parsed_args.buildOptions.split(',')


def choose_distribution():
    system = platform.system().lower()

    if system == "linux" or system == "linux2":
        if os.path.isfile("/etc/arch-release"):
            return "arch"
        with open("/etc/os-release") as f:
            for line in f:
                k, v = line.split("=")
                if k.strip() == 'ID':
                    return v.strip().replace('"', '').split(' ')[0]
    elif system == "darwin":
        return OSX_DISTRIBUTION_NAME
    elif system == "windows":
        return WIN32_DISTRIBUTION_NAME

    return 'Unknown'


def buildPlugin(pluginPath, processor, distribution, buildOptions=''):
    if distribution == WIN32_DISTRIBUTION_NAME:
        if (buildOptions):
            with open(f"{pluginPath}/package.json") as f:
                defaultPackage = json.load(f)
                package = defaultPackage.copy()
                package['defines'] = []
                for option in buildOptions:
                    package['defines'].append(option)
                f.close()
            with open(f"{pluginPath}/package.json", 'w') as f:
                json.dump(package, f, indent=4)
                f.close()
        subprocess.run([
            sys.executable, os.path.join(
                os.getcwd(), "../daemon/compat/msvc/winmake.py"),
            "-P",
            "-fb", pluginPath.split('/')[-1]
        ], check=True)
        if (buildOptions):
            with open(f"{pluginPath}/package.json", "w") as f:
                json.dump(defaultPackage, f, indent=4)
                f.close()
        return

    environ = os.environ.copy()

    install_args = []

    if distribution == ANDROID_DISTRIBUTION_NAME:
        install_args.append('-t')
        install_args.append(ANDROID_DISTRIBUTION_NAME)
    if processor:
        install_args.append('-c')
        install_args.append(processor)
    install_args.append('-p')
    install_args.append(str(multiprocessing.cpu_count()))

    subprocess.check_call(['chmod', '+x', pluginPath + "/build.sh"])
    return subprocess.run([pluginPath + "/build.sh"] +
                          install_args, env=environ, check=True)


def main():
    args = parse()
    currentDir = os.getcwd()

    for i, plugin in enumerate(args.projects):
        os.chdir(currentDir + "/" + plugin)
        buildPlugin(
            currentDir + "/" + plugin,
            args.processor[i],
            args.distribution,
            args.buildOptions)


if __name__ == "__main__":
    main()
