#!/usr/bin/env python3
#
# Copyright 2018 - 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.

"""Project information."""

from __future__ import absolute_import

import logging
import os

from aidegen import constant
from aidegen.lib import common_util
from aidegen.lib import errors
from aidegen.lib import module_info
from aidegen.lib import project_config
from aidegen.lib import source_locator

from atest import atest_utils

_CONVERT_MK_URL = ('https://android.googlesource.com/platform/build/soong/'
                   '#convert-android_mk-files')
_ANDROID_MK_WARN = (
    '{} contains Android.mk file(s) in its dependencies:\n{}\nPlease help '
    'convert these files into blueprint format in the future, otherwise '
    'AIDEGen may not be able to include all module dependencies.\nPlease visit '
    '%s for reference on how to convert makefile.' % _CONVERT_MK_URL)
_ROBOLECTRIC_MODULE = 'Robolectric_all'
_NOT_TARGET = ('Module %s\'s class setting is %s, none of which is included in '
               '%s, skipping this module in the project.')
# The module fake-framework have the same package name with framework but empty
# content. It will impact the dependency for framework when referencing the
# package from fake-framework in IntelliJ.
_EXCLUDE_MODULES = ['fake-framework']
_DISABLE_ROBO_BUILD_ENV_VAR = {'DISABLE_ROBO_RUN_TESTS': 'true'}
# When we use atest_utils.build(), there is a command length limit on
# soong_ui.bash. We reserve 5000 characters for rewriting the command line
# in soong_ui.bash.
_CMD_LENGTH_BUFFER = 5000
# For each argument, it need a space to separate following argument.
_BLANK_SIZE = 1


class ProjectInfo:
    """Project information.

    Users should call config_project first before starting using ProjectInfo.

    Class attributes:
        modules_info: A AidegenModuleInfo instance whose name_to_module_info is
                      combining module-info.json with module_bp_java_deps.json.

    Attributes:
        project_absolute_path: The absolute path of the project.
        project_relative_path: The relative path of the project to
                               common_util.get_android_root_dir().
        project_module_names: A set of module names under project_absolute_path
                              directory or it's subdirectories.
        dep_modules: A dict has recursively dependent modules of
                     project_module_names.
        git_path: The project's git path.
        iml_path: The project's iml file path.
        source_path: A dictionary to keep following data:
                     source_folder_path: A set contains the source folder
                                         relative paths.
                     test_folder_path: A set contains the test folder relative
                                       paths.
                     jar_path: A set contains the jar file paths.
                     jar_module_path: A dictionary contains the jar file and
                                      the module's path mapping, only used in
                                      Eclipse.
                     r_java_path: A set contains the relative path to the
                                  R.java files, only used in Eclipse.
                     srcjar_path: A source content descriptor only used in
                                  IntelliJ.
                                  e.g. out/.../aapt2.srcjar!/
                                  The "!/" is a content descriptor for
                                  compressed files in IntelliJ.
        is_main_project: A boolean to verify the project is main project.
    """

    modules_info = None

    def __init__(self, target=None, is_main_project=False):
        """ProjectInfo initialize.

        Args:
            target: Includes target module or project path from user input, when
                    locating the target, project with matching module name of
                    the given target has a higher priority than project path.
            is_main_project: A boolean, default is False. True if the target is
                             the main project, otherwise False.
        """
        rel_path, abs_path = common_util.get_related_paths(self.modules_info,
                                                           target)
        self.module_name = self._get_target_name(target, abs_path)
        self.is_main_project = is_main_project
        self.project_module_names = set(
            self.modules_info.get_module_names(rel_path))
        self.project_relative_path = rel_path
        self.project_absolute_path = abs_path
        self.git_path = ''
        self.iml_path = ''
        self._set_default_modues()
        self._init_source_path()
        self.dep_modules = self.get_dep_modules()
        self._filter_out_modules()
        self._display_convert_make_files_message()

    def _set_default_modues(self):
        """Append default hard-code modules, source paths and jar files.

        1. framework: Framework module is always needed for dependencies but it
            might not always be located by module dependency.
        2. org.apache.http.legacy.stubs.system: The module can't be located
            through module dependency. Without it, a lot of java files will have
            error of "cannot resolve symbol" in IntelliJ since they import
            packages android.Manifest and com.android.internal.R.
        """
        # TODO(b/112058649): Do more research to clarify how to remove these
        #                    hard-code sources.
        self.project_module_names.update(
            ['framework', 'org.apache.http.legacy.stubs.system'])

    def _init_source_path(self):
        """Initialize source_path dictionary."""
        self.source_path = {
            'source_folder_path': set(),
            'test_folder_path': set(),
            'jar_path': set(),
            'jar_module_path': dict(),
            'r_java_path': set(),
            'srcjar_path': set()
        }

    def _display_convert_make_files_message(self):
        """Show message info users convert their Android.mk to Android.bp."""
        mk_set = set(self._search_android_make_files())
        if mk_set:
            print('\n{} {}\n'.format(
                common_util.COLORED_INFO('Warning:'),
                _ANDROID_MK_WARN.format(self.module_name, '\n'.join(mk_set))))

    def _search_android_make_files(self):
        """Search project and dependency modules contain Android.mk files.

        If there is only Android.mk but no Android.bp, we'll show the warning
        message, otherwise we won't.

        Yields:
            A string: the relative path of Android.mk.
        """
        if (common_util.exist_android_mk(self.project_absolute_path) and
                not common_util.exist_android_bp(self.project_absolute_path)):
            yield '\t' + os.path.join(self.project_relative_path,
                                      constant.ANDROID_MK)
        for mod_name in self.dep_modules:
            rel_path, abs_path = common_util.get_related_paths(
                self.modules_info, mod_name)
            if rel_path and abs_path:
                if (common_util.exist_android_mk(abs_path)
                        and not common_util.exist_android_bp(abs_path)):
                    yield '\t' + os.path.join(rel_path, constant.ANDROID_MK)

    def _get_modules_under_project_path(self, rel_path):
        """Find modules under the rel_path.

        Find modules whose class is qualified to be included as a target module.

        Args:
            rel_path: A string, the project's relative path.

        Returns:
            A set of module names.
        """
        logging.info('Find modules whose class is in %s under %s.',
                     constant.TARGET_CLASSES, rel_path)
        modules = set()
        for name, data in self.modules_info.name_to_module_info.items():
            if common_util.is_project_path_relative_module(data, rel_path):
                if module_info.AidegenModuleInfo.is_target_module(data):
                    modules.add(name)
                else:
                    logging.debug(_NOT_TARGET, name, data['class'],
                                  constant.TARGET_CLASSES)
        return modules

    def _get_robolectric_dep_module(self, modules):
        """Return the robolectric module set as dependency if any module is a
           robolectric test.

        Args:
            modules: A set of modules.

        Returns:
            A set with a robolectric_all module name if one of the modules
            needs the robolectric test module. Otherwise return empty list.
        """
        for module in modules:
            if self.modules_info.is_robolectric_test(module):
                return set([_ROBOLECTRIC_MODULE])
        return set()

    def _filter_out_modules(self):
        """Filter out unnecessary modules."""
        for module in _EXCLUDE_MODULES:
            self.dep_modules.pop(module, None)

    def get_dep_modules(self, module_names=None, depth=0):
        """Recursively find dependent modules of the project.

        Find dependent modules by dependencies parameter of each module.
        For example:
            The module_names is ['m1'].
            The modules_info is
            {
                'm1': {'dependencies': ['m2'], 'path': ['path_to_m1']},
                'm2': {'path': ['path_to_m4']},
                'm3': {'path': ['path_to_m1']}
                'm4': {'path': []}
            }
            The result dependent modules are:
            {
                'm1': {'dependencies': ['m2'], 'path': ['path_to_m1']
                       'depth': 0},
                'm2': {'path': ['path_to_m4'], 'depth': 1},
                'm3': {'path': ['path_to_m1'], 'depth': 0}
            }
            Note that:
                1. m4 is not in the result as it's not among dependent modules.
                2. m3 is in the result as it has the same path to m1.

        Args:
            module_names: A set of module names.
            depth: An integer shows the depth of module dependency referenced by
                   source. Zero means the max module depth.

        Returns:
            deps: A dict contains all dependent modules data of given modules.
        """
        dep = {}
        children = set()
        if not module_names:
            module_names = self.project_module_names
            module_names.update(self._get_modules_under_project_path(
                self.project_relative_path))
            module_names.update(self._get_robolectric_dep_module(module_names))
            self.project_module_names = set()
        for name in module_names:
            if (name in self.modules_info.name_to_module_info
                    and name not in self.project_module_names):
                dep[name] = self.modules_info.name_to_module_info[name]
                dep[name][constant.KEY_DEPTH] = depth
                self.project_module_names.add(name)
                if (constant.KEY_DEPENDENCIES in dep[name]
                        and dep[name][constant.KEY_DEPENDENCIES]):
                    children.update(dep[name][constant.KEY_DEPENDENCIES])
        if children:
            dep.update(self.get_dep_modules(children, depth + 1))
        return dep

    @staticmethod
    def generate_projects(targets):
        """Generate a list of projects in one time by a list of module names.

        Args:
            targets: A list of target modules or project paths from user input,
                     when locating the target, project with matched module name
                     of the target has a higher priority than project path.

        Returns:
            List: A list of ProjectInfo instances.
        """
        return [ProjectInfo(target, i == 0) for i, target in enumerate(targets)]

    @staticmethod
    def _get_target_name(target, abs_path):
        """Get target name from target's absolute path.

        If the project is for entire Android source tree, change the target to
        source tree's root folder name. In this way, we give IDE project file
        a more specific name. e.g, master.iml.

        Args:
            target: Includes target module or project path from user input, when
                    locating the target, project with matching module name of
                    the given target has a higher priority than project path.
            abs_path: A string, target's absolute path.

        Returns:
            A string, the target name.
        """
        if abs_path == common_util.get_android_root_dir():
            return os.path.basename(abs_path)
        return target

    def locate_source(self, build=True):
        """Locate the paths of dependent source folders and jar files.

        Try to reference source folder path as dependent module unless the
        dependent module should be referenced to a jar file, such as modules
        have jars and jarjar_rules parameter.
        For example:
            Module: asm-6.0
                java_import {
                    name: 'asm-6.0',
                    host_supported: true,
                    jars: ['asm-6.0.jar'],
                }
            Module: bouncycastle
                java_library {
                    name: 'bouncycastle',
                    ...
                    target: {
                        android: {
                            jarjar_rules: 'jarjar-rules.txt',
                        },
                    },
                }

        Args:
            build: A boolean default to true. If false, skip building jar and
                   srcjar files, otherwise build them.

        Example usage:
            project.source_path = project.locate_source()
            E.g.
                project.source_path = {
                    'source_folder_path': ['path/to/source/folder1',
                                           'path/to/source/folder2', ...],
                    'test_folder_path': ['path/to/test/folder', ...],
                    'jar_path': ['path/to/jar/file1', 'path/to/jar/file2', ...]
                }
        """
        if not hasattr(self, 'dep_modules') or not self.dep_modules:
            raise errors.EmptyModuleDependencyError(
                'Dependent modules dictionary is empty.')
        rebuild_targets = set()
        for module_name, module_data in self.dep_modules.items():
            module = self._generate_moduledata(module_name, module_data)
            module.locate_sources_path()
            self.source_path['source_folder_path'].update(module.src_dirs)
            self.source_path['test_folder_path'].update(module.test_dirs)
            self.source_path['r_java_path'].update(module.r_java_paths)
            self.source_path['srcjar_path'].update(module.srcjar_paths)
            self._append_jars_as_dependencies(module)
            rebuild_targets.update(module.build_targets)
        if project_config.ProjectConfig.get_instance().is_skip_build:
            return
        if rebuild_targets:
            if build:
                verbose = project_config.ProjectConfig.get_instance().verbose
                _batch_build_dependencies(verbose, rebuild_targets)
                self.locate_source(build=False)
            else:
                logging.warning('Jar or srcjar files build skipped:\n\t%s.',
                                '\n\t'.join(rebuild_targets))

    def _generate_moduledata(self, module_name, module_data):
        """Generate a module class to collect dependencies in IDE.

        The rules of initialize a module data instance: if ide_object isn't None
        and its ide_name is 'eclipse', we'll create an EclipseModuleData
        instance otherwise create a ModuleData instance.

        Args:
            module_name: Name of the module.
            module_data: A dictionary holding a module information.

        Returns:
            A ModuleData class.
        """
        ide_name = project_config.ProjectConfig.get_instance().ide_name
        if ide_name == constant.IDE_ECLIPSE:
            return source_locator.EclipseModuleData(
                module_name, module_data, self.project_relative_path)
        depth = project_config.ProjectConfig.get_instance().depth
        return source_locator.ModuleData(module_name, module_data, depth)

    def _append_jars_as_dependencies(self, module):
        """Add given module's jar files into dependent_data as dependencies.

        Args:
            module: A ModuleData instance.
        """
        if module.jar_files:
            self.source_path['jar_path'].update(module.jar_files)
            for jar in list(module.jar_files):
                self.source_path['jar_module_path'].update({
                    jar:
                    module.module_path
                })
        # Collecting the jar files of default core modules as dependencies.
        if constant.KEY_DEPENDENCIES in module.module_data:
            self.source_path['jar_path'].update([
                x for x in module.module_data[constant.KEY_DEPENDENCIES]
                if common_util.is_target(x, constant.TARGET_LIBS)
            ])

    @classmethod
    def multi_projects_locate_source(cls, projects):
        """Locate the paths of dependent source folders and jar files.

        Args:
            projects: A list of ProjectInfo instances. Information of a project
                      such as project relative path, project real path, project
                      dependencies.
        """
        for project in projects:
            project.locate_source()


def _batch_build_dependencies(verbose, rebuild_targets):
    """Batch build the jar or srcjar files of the modules if they don't exist.

    Command line has the max length limit, MAX_ARG_STRLEN, and
    MAX_ARG_STRLEN = (PAGE_SIZE * 32).
    If the build command is longer than MAX_ARG_STRLEN, this function will
    separate the rebuild_targets into chunks with size less or equal to
    MAX_ARG_STRLEN to make sure it can be built successfully.

    Args:
        verbose: A boolean, if true displays full build output.
        rebuild_targets: A set of jar or srcjar files which do not exist.
    """
    logging.info('Ready to build the jar or srcjar files. Files count = %s',
                 str(len(rebuild_targets)))
    arg_max = os.sysconf('SC_PAGE_SIZE') * 32 - _CMD_LENGTH_BUFFER
    rebuild_targets = list(rebuild_targets)
    for start, end in iter(_separate_build_targets(rebuild_targets, arg_max)):
        _build_target(rebuild_targets[start:end], verbose)


def _build_target(targets, verbose):
    """Build the jar or srcjar files.

    Use -k to keep going when some targets can't be built or build failed.
    Use -j to speed up building.

    Args:
        targets: A list of jar or srcjar files which need to build.
        verbose: A boolean, if true displays full build output.
    """
    build_cmd = ['-k', '-j']
    build_cmd.extend(list(targets))
    if not atest_utils.build(build_cmd, verbose, _DISABLE_ROBO_BUILD_ENV_VAR):
        message = ('Build failed!\n{}\nAIDEGen will proceed but dependency '
                   'correctness is not guaranteed if not all targets being '
                   'built successfully.'.format('\n'.join(targets)))
        print('\n{} {}\n'.format(common_util.COLORED_INFO('Warning:'), message))


def _separate_build_targets(build_targets, max_length):
    """Separate the build_targets by limit the command size to max command
    length.

    Args:
        build_targets: A list to be separated.
        max_length: The max number of each build command length.

    Yields:
        The start index and end index of build_targets.
    """
    arg_len = 0
    first_item_index = 0
    for i, item in enumerate(build_targets):
        arg_len = arg_len + len(item) + _BLANK_SIZE
        if arg_len > max_length:
            yield first_item_index, i
            first_item_index = i
            arg_len = len(item) + _BLANK_SIZE
    if first_item_index < len(build_targets):
        yield first_item_index, len(build_targets)
