#!/usr/bin/env python3
#
# Copyright (C) 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.
#
"""Utility functions for VNDK snapshot."""

import argparse
import glob
import logging
import os
import re
import subprocess
import sys

# Global Keys
#   All paths are relative to install_dir: prebuilts/vndk/v{version}
ROOT_BP_PATH = 'Android.bp'
COMMON_DIR_NAME = 'common'
COMMON_DIR_PATH = COMMON_DIR_NAME
COMMON_BP_PATH = os.path.join(COMMON_DIR_PATH, 'Android.bp')
CONFIG_DIR_PATH_PATTERN = '*/configs'
MANIFEST_FILE_NAME = 'manifest.xml'
MODULE_PATHS_FILE_NAME = 'module_paths.txt'
NOTICE_FILES_DIR_NAME = 'NOTICE_FILES'
NOTICE_FILES_DIR_PATH = os.path.join(COMMON_DIR_PATH, NOTICE_FILES_DIR_NAME)
BINDER32 = 'binder32'
MINIMUM_VNDK_VERSION = 28
SOONG_INTERMEDIATES_DIR = 'out/soong/.intermediates'
GENERATED_HEADERS_DIR = 'generated-headers'

def set_logging_config(verbose_level):
    verbose_map = (logging.WARNING, logging.INFO, logging.DEBUG)
    verbosity = min(verbose_level, 2)
    logging.basicConfig(
        format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s',
        level=verbose_map[verbosity])


def check_call(cmd):
    logging.debug('Running `{}`'.format(' '.join(cmd)))
    subprocess.check_call(cmd)


def check_output(cmd):
    logging.debug('Running `{}`'.format(' '.join(cmd)))
    output = subprocess.check_output(cmd, encoding='utf-8')
    logging.debug('Output: `{}`'.format(output))
    return output


def vndk_version_int(vndk_version):
    """Used for a type keyword argument in the argparse.
    It checks if vndk version is in the supported versions.
    """
    version_int = int(vndk_version)
    if version_int < MINIMUM_VNDK_VERSION:
        raise argparse.ArgumentTypeError(
            'The VNDK version {input} is not supported. '
            'It must be no smaller than {min_vndk}.'.format(
                input=version_int, min_vndk=MINIMUM_VNDK_VERSION))
    return version_int


def get_android_build_top():
    ANDROID_BUILD_TOP = os.getenv('ANDROID_BUILD_TOP')
    if not ANDROID_BUILD_TOP:
        print('Error: Missing ANDROID_BUILD_TOP env variable. Please run '
              '\'. build/envsetup.sh; lunch <build target>\'. Exiting script.')
        sys.exit(1)
    return ANDROID_BUILD_TOP


def join_realpath(root, *args):
    return os.path.realpath(os.path.join(root, *args))


def _get_dir_from_env(env_var, default):
    return os.path.realpath(os.getenv(env_var, default))


def get_out_dir(android_build_top):
    return _get_dir_from_env('OUT_DIR', join_realpath(android_build_top,
                                                      'out'))


def get_dist_dir(out_dir):
    return _get_dir_from_env('DIST_DIR', join_realpath(out_dir, 'dist'))


def get_snapshot_archs(install_dir):
    """Returns a list of VNDK snapshot arch flavors under install_dir.

    Args:
      install_dir: string, absolute path of prebuilts/vndk/v{version}
    """
    archs = []
    for file in glob.glob('{}/*'.format(install_dir)):
        basename = os.path.basename(file)
        if os.path.isdir(file) and basename != COMMON_DIR_NAME:
            archs.append(basename)
    return sorted(archs)


def prebuilt_arch_from_path(path):
    """Extracts arch of prebuilts from path relative to install_dir.

    Args:
      path: string, path relative to prebuilts/vndk/v{version}

    Returns:
      string, arch of prebuilt (e.g., 'arm' or 'arm64' or 'x86' or 'x86_64')
    """
    return path.split('/')[1].split('-')[1]


def snapshot_arch_from_path(path):
    """Extracts VNDK snapshot arch from path relative to install_dir.

    Args:
      path: string, path relative to prebuilts/vndk/v{version}

    Returns:
      string, VNDK snapshot arch (e.g. 'arm64')
    """
    return path.split('/')[0]


def find(path, names):
    """Returns a list of files in a directory that match the given names.

    Args:
      path: string, absolute path of directory from which to find files
      names: list of strings, names of the files to find
    """
    found = []
    for root, _, files in os.walk(path):
        for file_name in sorted(files):
            if file_name in names:
                abspath = os.path.abspath(os.path.join(root, file_name))
                rel_to_root = abspath.replace(os.path.abspath(path), '')
                found.append(rel_to_root[1:])  # strip leading /
    return found


def fetch_artifact(branch, build, pattern, destination='.'):
    """Fetches build artifacts from Android Build server.

    Args:
      branch: string, branch to pull build artifacts from
      build: string, build number to pull build artifacts from
      pattern: string, pattern of build artifact file name
      destination: string, destination to pull build artifact to
    """
    fetch_artifact_path = '/google/data/ro/projects/android/fetch_artifact'
    cmd = [
        fetch_artifact_path, '--branch', branch, '--target=vndk', '--bid',
        build, pattern, destination
    ]
    check_call(cmd)


def get_latest_vndk_bid(branch):
    """Get the build id of the latest green build of the vndk target
    from the Android Build Server.

    Args:
      branch: string, branch to pull build artifacts from

    Returns:
      string: bid of the latest green build
    """
    ab_tool_path = '/google/bin/releases/android/ab/ab.par'
    cmd = [
        ab_tool_path, 'lkgb', '--branch', branch, '--target', 'vndk'
    ]

    # output will be 'branch target build_id status successful'
    output = check_output(cmd).strip()

    # return build_id from the output
    return output.split()[2]
