#!/usr/bin/env python3
#
# Copyright 2017 - The Android Open Source Project
#
# 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.
from distutils import cmd
from distutils import log
import subprocess
import os
import shutil
import setuptools
from setuptools.command import test
import sys

install_requires = [
    'backoff',
    # Future needs to have a newer version that contains urllib.
    'future>=0.16.0',
    # Latest version of mock (4.0.0b) causes a number of compatibility issues with ACTS unit tests
    # b/148695846, b/148814743
    'mock==3.0.5',
    'pyserial',
    'pyyaml>=5.1',
    'pynacl==1.4.0',
    'protobuf>=3.14.0',
    'retry',
    'requests',
    'scapy',
    'pylibftdi',
    'xlsxwriter',
    'mobly>=1.10.0',
    'grpcio',
    'Monsoon',
    # paramiko-ng is needed vs paramiko as currently paramiko does not support
    # ed25519 ssh keys, which is what Fuchsia uses.
    'paramiko-ng',
    'dlipower',
    'usbinfo',
    'zeroconf'
]

# numpy and scipy version matrix per:
# https://docs.scipy.org/doc/scipy/reference/toolchain.html
if sys.version_info < (3, 6):
    # Python <= 3.5 uses scipy up to 1.4 and numpy up to 1.18.x
    # b/157117302:Monsoon dependency
    install_requires.append('scipy<1.5')
    install_requires.append('numpy<1.19')
elif sys.version_info < (3, 7):
    # Python 3.6 uses scipy up to 1.5 and numpy up to 1.19.x
    install_requires.append('scipy<1.6')
    install_requires.append('numpy<1.20')
elif sys.version_info < (3, 8):
    # Python 3.7 uses latest scipy up to 1.7.x and numpy up to 1.21.x
    install_requires.append('scipy<1.8')
    install_requires.append('numpy<1.22')
else:
    # Python 3.8+ is supported by latest scipy and numpy
    install_requires.append('scipy')
    install_requires.append('numpy')

if sys.version_info < (3, ):
    install_requires.append('enum34')
    install_requires.append('statistics')
    # "futures" is needed for py2 compatibility and it only works in 2.7
    install_requires.append('futures')
    install_requires.append('py2-ipaddress')
    install_requires.append('subprocess32')

DEV_PACKAGES = ['shiv']

framework_dir = os.path.dirname(os.path.realpath(__file__))


class PyTest(test.test):
    """Class used to execute unit tests using PyTest. This allows us to execute
    unit tests without having to install the package.
    """

    def finalize_options(self):
        test.test.finalize_options(self)
        self.test_args = ['-x', "tests"]
        self.test_suite = True

    def run_tests(self):
        test_path = os.path.join(framework_dir,
                                 '../tests/meta/ActsUnitTest.py')
        result = subprocess.Popen('python3 %s' % test_path,
                                  stdout=sys.stdout,
                                  stderr=sys.stderr,
                                  shell=True)
        result.communicate()
        sys.exit(result.returncode)


class ActsInstallDependencies(cmd.Command):
    """Installs only required packages

    Installs all required packages for acts to work. Rather than using the
    normal install system which creates links with the python egg, pip is
    used to install the packages.
    """

    description = 'Install dependencies needed for acts to run on this machine.'
    user_options = []

    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        install_args = [sys.executable, '-m', 'pip', 'install']
        subprocess.check_call(install_args + ['--upgrade', 'pip'])
        required_packages = self.distribution.install_requires

        for package in required_packages:
            self.announce('Installing %s...' % package, log.INFO)
            subprocess.check_call(install_args +
                                  ['-v', '--no-cache-dir', package])

        self.announce('Dependencies installed.')


class ActsUninstall(cmd.Command):
    """Acts uninstaller.

    Uninstalls acts from the current version of python. This will attempt to
    import acts from any of the python egg locations. If it finds an import
    it will use the modules file location to delete it. This is repeated until
    acts can no longer be imported and thus is uninstalled.
    """

    description = 'Uninstall acts from the local machine.'
    user_options = []

    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def uninstall_acts_module(self, acts_module):
        """Uninstalls acts from a module.

        Args:
            acts_module: The acts module to uninstall.
        """
        for acts_install_dir in acts_module.__path__:
            self.announce('Deleting acts from: %s' % acts_install_dir,
                          log.INFO)
            shutil.rmtree(acts_install_dir)

    def run(self):
        """Entry point for the uninstaller."""
        # Remove the working directory from the python path. This ensures that
        # Source code is not accidentally targeted.
        if framework_dir in sys.path:
            sys.path.remove(framework_dir)

        if os.getcwd() in sys.path:
            sys.path.remove(os.getcwd())

        try:
            import acts as acts_module
        except ImportError:
            self.announce('Acts is not installed, nothing to uninstall.',
                          level=log.ERROR)
            return

        while acts_module:
            self.uninstall_acts_module(acts_module)
            try:
                del sys.modules['acts']
                import acts as acts_module
            except ImportError:
                acts_module = None

        self.announce('Finished uninstalling acts.')


def main():
    scripts = [
        os.path.join('acts', 'bin', 'act.py'),
        os.path.join('acts', 'bin', 'monsoon.py')
    ]
    # cd to framework directory so the correct package namespace is found
    os.chdir(framework_dir)
    setuptools.setup(name='acts',
                     version='0.9',
                     description='Android Comms Test Suite',
                     license='Apache2.0',
                     packages=setuptools.find_packages(),
                     include_package_data=True,
                     tests_require=['pytest'],
                     install_requires=install_requires,
                     extras_require={'dev': DEV_PACKAGES},
                     scripts=scripts,
                     cmdclass={
                         'test': PyTest,
                         'install_deps': ActsInstallDependencies,
                         'uninstall': ActsUninstall
                     },
                     url="http://www.android.com/")

    if {'-u', '--uninstall', 'uninstall'}.intersection(sys.argv):
        installed_scripts = [
            '/usr/local/bin/act.py', '/usr/local/bin/monsoon.py'
        ]
        for act_file in installed_scripts:
            if os.path.islink(act_file):
                os.unlink(act_file)
            elif os.path.exists(act_file):
                os.remove(act_file)


if __name__ == '__main__':
    main()
