#
#    Copyright (c) 2020 Project CHIP Authors
#    Copyright (c) 2019 Google LLC.
#    All rights reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License");
#    you may not use this file except in compliance with the License.
#    You may obtain a copy of the License at
#
#        http://www.apache.org/licenses/LICENSE-2.0
#
#    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 License for the specific language governing permissions and
#    limitations under the License.
#

#
#    Description:
#      Builds a Python wheel package for Matter.
#

from __future__ import absolute_import

import argparse
import json
import os
import shutil

from setuptools import Distribution, setup

parser = argparse.ArgumentParser(
    description='Build PIP package for Matter using Matter core components '
                'generated during the build and python source code')
parser.add_argument('--package-name', default='matter',
                    help='configure the python package name')
parser.add_argument('--build-number', default='1.0.0',
                    help='configure the python package build number')
parser.add_argument('--build-dir', help='directory to build in')
parser.add_argument('--dist-dir', help='directory to place distribution in')
parser.add_argument('--manifest', help='list of files to package')
parser.add_argument(
    '--plat-name', help='platform name to embed in generated filenames')
parser.add_argument(
    '--lib-name', help='the native library to include (if any)', default=None)

args = parser.parse_args()


class InstalledScriptInfo:
    """Information holder about a script that is to be installed."""

    def __init__(self, name):
        self.name = name
        self.installName = os.path.splitext(name)[0]

# Make sure wheel is not considered pure and avoid shared libraries in purelib
# folder.


class BinaryDistribution(Distribution):
    def has_ext_modules(foo):
        return True


packageName = args.package_name
libName = args.lib_name
packageVersion = args.build_number

# Record the current directory at the start of execution.
curDir = os.curdir

manifestFile = os.path.abspath(args.manifest)
buildDir = os.path.abspath(args.build_dir)
distDir = os.path.abspath(args.dist_dir)

# Use a temporary directory within the build directory to assemble the components
# for the installable package.
tmpDir = os.path.join(buildDir, "matter-wheel-components")

with open(manifestFile) as f:
    manifest = json.load(f)

try:

    #
    # Perform a series of setup steps prior to creating the package...
    #

    # Create the temporary components directory.
    if os.path.isdir(tmpDir):
        shutil.rmtree(tmpDir)
    os.makedirs(tmpDir, exist_ok=True)

    # Switch to the temporary directory. (Foolishly, setuptools relies on the current directory
    # for many of its features.)
    os.chdir(tmpDir)

    manifestBase = os.path.dirname(manifestFile)
    for entry in manifest['files']:
        srcDir = os.path.join(manifestBase, entry['src_dir'])
        for path in entry['sources']:
            srcFile = os.path.join(srcDir, path)
            dstFile = os.path.join(tmpDir, path)
            os.makedirs(os.path.dirname(dstFile), exist_ok=True)
            shutil.copyfile(srcFile, dstFile)

    installScripts = [InstalledScriptInfo(script) for script in manifest['scripts']]
    for script in installScripts:
        os.rename(os.path.join(tmpDir, script.name),
                  os.path.join(tmpDir, script.installName))

    requiredPackages = manifest['package_reqs']

    #
    # Build the package...
    #
    packages = manifest['packages']

    print("packageName: {}".format(packageName))
    print("libName: {}".format(libName))

    # Invoke the setuptools 'bdist_wheel' command to generate a wheel
    # containing Matter Python packages, shared libraries and scripts.
    setup(
        name=packageName,
        version=packageVersion,
        description="Python-base APIs and tools for Matter SDK",
        url="https://github.com/project-chip/connectedhomeip",
        classifiers=[
            "Intended Audience :: Developers",
            "License :: OSI Approved :: Apache Software License",
            "Programming Language :: Python :: 3"
        ],
        python_requires=">=3.11",
        packages=packages,
        package_dir={
            # By default, look in the tmp directory for packages/modules to be included.
            '': tmpDir,
        },
        package_data={
            packages[0]: [
                libName
            ]
        } if libName else {},
        scripts=[os.path.join(tmpDir, script.installName) for script in installScripts],
        install_requires=requiredPackages,
        options={
            'bdist_wheel': {
                'universal': False,
                # Place the generated .whl in the dist directory.
                'dist_dir': distDir,
                'py_limited_api': 'cp311',
                'plat_name': args.plat_name,
            },
            'egg_info': {
                # Place the .egg-info subdirectory in the tmp directory.
                'egg_base': tmpDir
            }
        },
        distclass=BinaryDistribution if libName else None,
        script_args=['clean', '--all', 'bdist_wheel']
    )

finally:

    # Switch back to the initial current directory.
    os.chdir(curDir)

    # Remove the temporary directory.
    if os.path.isdir(tmpDir):
        shutil.rmtree(tmpDir)
