#
# Copyright (C) 2016 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.
#

"""A class to assist with sysroots."""


import os
import shutil


def _FilterHeaders(filename):
    return filename.endswith('.h')


class SysrootUtil(object):
    """A class to assist with setting up sysroots.

    Attributes:
        sysroot - the sysroot this instance helps with.
    """

    # Includes to provide in the sysroot.
    # (lib, recurse, filter)
    DEFAULT_INCLUDES = [
        ('bionic/libc/include', True, _FilterHeaders),
        ('bionic/libc/kernel/uapi/asm-generic/..', True, _FilterHeaders),
        ('bionic/libc/kernel/uapi/linux/..', True, _FilterHeaders),
        ('external/zlib', False, _FilterHeaders),
        ('system/core/include', True, _FilterHeaders)
    ]
    DEFAULT_ARCH_INCLUDES = {
        'arm': [('bionic/libc/kernel/uapi/asm-arm', True, _FilterHeaders),
                ('bionic/libc/arch-arm/include', True, _FilterHeaders)],
        'mips': [('bionic/libc/kernel/uapi/asm-mips', True, _FilterHeaders),
                 ('bionic/libc/arch-mips/include', True, _FilterHeaders)],
        'x86': [('bionic/libc/kernel/uapi/asm-x86', True, _FilterHeaders),
                ('bionic/libc/arch-x86/include', True, _FilterHeaders)],
    }

    # Libs to provide in the sysroot.
    STATIC_PATH_FORMAT = '{0}_intermediates/{0}.a'
    DEFAULT_STATIC_LIBS = ['libc', 'libc++_static', 'libm', 'libz']
    DEFAULT_SHARED_LIBS = ['crtbegin_so.o',
                           'crtbegin_dynamic.o',
                           'crtbegin_static.o',
                           'crtend_android.o',
                           'crtend_so.o',
                           'libc.so',
                           'libc++.so',
                           'libdl.so',
                           'libm.so',
                           'libz.so']

    DEFAULT_LIB_RENAMES = {
        'libc++.so': 'libstdc++.so',
        'libc++_static.a': 'libstdc++.a'
    }

    # Some defaults for where things go.
    DEFAULT_INCLUDE_DIR = os.path.join('usr', 'include')
    DEFAULT_LIB_DIR = os.path.join('usr', 'lib')
    ADDITIONAL_INCLUDE_EXTENSION = 'brillo'

    # Libcxx gets special treatment.
    LIBCXX_HEADERS = 'external/libcxx/include'
    LIBCXX_INCLUDE_DIR = os.path.join(DEFAULT_INCLUDE_DIR, 'c++')

    # pkg-config constants.
    PC_DIR = os.path.join('usr', 'share', 'pkgconfig')
    # For this format:
    # {0} - lib name
    # {1} - version
    # {2} - dependencies
    # {3} - normalized lib name ('lib' prefix removed)
    # Note that if this format changes where to expect things,
    # also change the AddProvidedLib function.
    PC_FILE_FORMAT = ('prefix=/usr\n'
                      'exec_prefix=${{prefix}}\n'
                      'libdir=${{exec_prefix}}/lib\n'
                      'includedir=${{exec_prefix}}/include/' +
                      ADDITIONAL_INCLUDE_EXTENSION + '/{0}\n'
                      '\n'
                      'Name: {0}\n'
                      'Description: {0} for Brillo\n'
                      'Version: {1}\n'
                      'Requires: {2}\n'
                      'Libs: -L${{libdir}} -l{3}\n'
                      'Cflags: -I${{includedir}}\n')

    def __init__(self, sysroot, platform):
        self.sysroot = sysroot
        self.platform = platform

    def _FormatForCopy(self, src, dest):
        """Helper to account for special formatting signals.

        Given a path to copy from and path to copy to, returns a pair suitable
        to input into sysroot.AddDir.

        Special format A/B/.. designates wanting only B when A has several
        subdirs.

        Args:
            src: the path to copy from. Relative to the OS.
            dest: the path to copy to. Relative to the sysroot.

        Returns:
            (result_src, result_dest), src and dest transformed and ready
            to be passed into sysroot.AddDir.
        """
        result_src = self.platform.os.path(src)
        result_dest = dest
        if src.endswith('/..'):
            basename = os.path.basename(src[:-3])
            result_src = os.path.join(result_src, basename)
            result_dest = os.path.join(result_dest, basename)
        return (result_src, result_dest)

    def _AddPkgConfigFile(self, lib, deps, version):
        """Writes a .pc file for a lib in the sysroot.

        Args:
            lib: the name of the library for this .pc file.
            deps: a space separated string of library names this library
                depends on.
            version: the version of this library.

        Raises:
            IOError if the file write fails.
        """
        dest_dir = self.PC_DIR

        normalized_lib = lib
        if lib.startswith('lib'):
            normalized_lib = lib[3:]
        self.sysroot.WriteFile(
            os.path.join(dest_dir, lib + '.pc'),
            self.PC_FILE_FORMAT.format(lib, version, deps, normalized_lib))

    def AddSharedLib(self, lib_src, name, deps, includes, suffix=None):
        """Adds a library to the sysroot.

        Copies in the .so file, copies in includes, and generates a pkg-config
        file.

        Args:
            lib_src: path where prebuilt shared libs can be found.
            name: the name of the library to add.
            deps: a space-separated string of library names lib is dependent on.
            includes: a list of directories with headers for lib.
            suffix: (optional) a suffix to append to the lib name when added
                to the sysroot.

        Raises:
            IOError: If there are any issues adding the necessary files
                to the sysroot.
        """
        suffixed_name = name
        if suffix:
            suffixed_name += '-' + suffix

        # Set up destinations.
        # NOTE: if these change, also update the PC_FILE_FORMAT.
        lib_dest = self.DEFAULT_LIB_DIR
        include_dest = os.path.join(self.DEFAULT_INCLUDE_DIR,
                                    self.ADDITIONAL_INCLUDE_EXTENSION,
                                    suffixed_name)
        self.sysroot.Makedirs(lib_dest)
        self.sysroot.Makedirs(include_dest)

        errors = []

        # Get the .so file.
        try:
            self.sysroot.AddFile(os.path.join(lib_src, name + '.so'),
                                 os.path.join(lib_dest, suffixed_name + '.so'))
        except IOError as e:
            errors.append('.so file: {}'.format(e))

        # Copy includes (.h files only) over to sysroot.
        for include in includes:
            (src, dest) = self._FormatForCopy(include, include_dest)
            try:
                self.sysroot.AddDir(src, dest, filter_func=_FilterHeaders)
            except IOError as e:
                errors.append('include {}: {}'.format(include, e))

        # Write the .pc file.
        try:
            self._AddPkgConfigFile(suffixed_name, deps,
                                   self.platform.os.version)
        except IOError as e:
            errors.append('.pc file: {}'.format(e))

        if errors:
            raise IOError('Failed to add components for {}: {}'.format(
                suffixed_name, errors))

    def AddSharedLibsFromCSV(self, lib_src, csv_file, suffix=None):
        """Add libraries read from a csv file to the sysroot.

        CSV file format is one line header, followed by lines of the form
            libname, deps, include_dirs

        Args:
            lib_src: path where prebuilt shared libs can be found.
            csv_file: path to the file to add libs from.
            suffix: (optional) a suffix to append to all the lib names when
                added to the sysroot.

        Raises:
            IOError: if file can't be found or adding any lib fails.
            ValueError: if any line in the file doesn't meet format
                expectations.
        """
        libs = []
        try:
            with open(csv_file) as pkg_list:
                # Skip the header line
                pkg_list.readline()
                # Read in all the remaining lines
                for line in pkg_list:
                    lib_details = [pkg.strip() for pkg in line.split(',')]
                    if len(lib_details) != 3:
                        raise ValueError(('Line in package csv file "{0}" has '
                                          'the incorrect number of items '
                                          '(expected 3): {1}').format(csv_file,
                                                                      line))
                    libs.append(lib_details)
        except IOError as e:
            raise IOError('Failed to open lib list: {0}'.format(e))

        errors = []
        for (name, deps, include_str) in libs:
            try:
                self.AddSharedLib(lib_src, name, deps, include_str.split(),
                                  suffix)
            except IOError as e:
                errors.append(e)

        if errors:
            raise IOError('Failed to add libs from csv {0}: {1}'.format(
                csv_file, errors))

    def SetupBaseSysroot(self, arch, shared_libs, static_libs,
                         base_sysroot=None):
        """Sets up a sysroot dir from defaults.

        Standard includes and lib files are added to
        <sysroot>/usr/{include, lib}.

        Args:
            arch: the architecture to setup a sysroot for.
            shared_libs: path where prebuilt shared libs can be found.
            static_libs: path where prebuilt static libs can be found.
            base_sysroot: (optional). If provided, copies all files of the
                sysroot found at this path, with priority over other files.

        Raises:
            IOError: if anything fails, specifying which things failed.
        """
        errors = []

        # Copy in includes.
        self.sysroot.Makedirs(self.DEFAULT_INCLUDE_DIR)
        for (include, recurse, filter_func) in (
                self.DEFAULT_INCLUDES + self.DEFAULT_ARCH_INCLUDES[arch]):
            (src, dest) = self._FormatForCopy(include, self.DEFAULT_INCLUDE_DIR)
            try:
                self.sysroot.AddDir(src, dest, recurse, filter_func)
            except IOError as e:
                errors.append('{}: {}'.format(include, e))

        # Handle libcxx.
        (src, dest) = self._FormatForCopy(self.LIBCXX_HEADERS,
                                          self.LIBCXX_INCLUDE_DIR)
        try:
            self.sysroot.AddDir(src, dest)
        except IOError as e:
            errors.append(self.LIBCXX_HEADERS)

        # Copy in libs.
        self.sysroot.Makedirs(self.DEFAULT_LIB_DIR)
        for lib in self.DEFAULT_SHARED_LIBS:
            try:
                self.sysroot.AddFile(os.path.join(shared_libs, lib),
                                     self.DEFAULT_LIB_DIR)
            except IOError as e:
                errors.append(lib)
        for lib in self.DEFAULT_STATIC_LIBS:
            try:
                self.sysroot.AddFile(
                    os.path.join(static_libs,
                                 self.STATIC_PATH_FORMAT.format(lib)),
                    self.DEFAULT_LIB_DIR)
            except IOError as e:
                errors.append(lib)

        # Do some renaming.
        for (src, dest) in self.DEFAULT_LIB_RENAMES.iteritems():
            try:
                shutil.move(self.sysroot.Path(self.DEFAULT_LIB_DIR, src),
                            self.sysroot.Path(self.DEFAULT_LIB_DIR, dest))
            except IOError as e:
                errors.append('rename {0} --> {1}'.format(src, dest))

        # Base our sysroot on another.
        # We do this after copying in defaults to give this base priority.
        if base_sysroot:
            try:
                self.sysroot.AddDir(base_sysroot)
            except IOError as e:
                errors.append(base_sysroot)

        if errors:
            raise IOError(
                'Failed to add {0} during sysroot setup.'.format(errors))
