#!/usr/bin/python
#
# Copyright (C) 2015 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.

"""Merge packages into the target image."""

from __future__ import print_function

import argparse
import errno
import glob
import os
import shutil
import sys


def makedirs(path):
    """Create all the dirs for |path| ignoring already existing errors."""
    try:
        os.makedirs(path)
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise


def unlink(path):
    """Delete |path| ignoring missing paths."""
    try:
        os.unlink(path)
    except OSError as e:
        if e.errno != errno.ENOENT:
            raise


def load_contents(pkg, root, filter=None):
    """Read the CONTENTS file for |pkg| from |root|."""
    if not filter:
        filter = lambda x: True

    ret = []

    contents = os.path.join(root, 'var', 'db', 'pkg', pkg + '-*', 'CONTENTS')
    files = glob.glob(contents)
    if not files:
        raise Exception('No packages found matching %s' % pkg)

    with open(files[0]) as f:
        for line in f.read().splitlines():
            line = line.strip()
            if not line:
                continue
            typ, data = line.split(' ', 1)
            if typ == 'obj':
                path, _hash, _mtime = data.rsplit(' ', 2)
                if filter(path):
                    ret.append(('obj', path))
            elif typ == 'sym':
                source, target = data.split(' -> ', 1)
                target, _mtime = target.rsplit(' ', 1)
                if filter(source):
                    ret.append(('sym', source, target))
            elif typ == 'dir':
                pass
            else:
                raise Exception('Unhandled entry: %s' % line)

    return ret


def ignore_files(path):
    """Figure out which files we actually care about."""
    if path.startswith('/usr/share/doc'):
        return False
    elif path.startswith('/usr/share/gtk-doc'):
        return False
    elif path.startswith('/usr/share/info'):
        return False
    elif path.startswith('/usr/share/man'):
        return False
    elif path.startswith('/usr/include'):
        return False
    elif path.startswith('/usr/bin') and path.endswith('-config'):
        return False
    elif path.startswith('/usr/lib'):
        if path.endswith('.a'):
            return False
        elif path.endswith('.pc'):
            return False

    return True


def merge(pkg, input_root, output_root, make_root, verbose=0):
    """Merge |pkg| from |input_root| to |output_root|."""
    print('Merging %s ' % pkg, end='')
    if verbose:
        print('from %s to %s' % (input_root, output_root))

    # TODO: Grab a lock for |pkg|.

    # First get the file listing to merge.
    contents = load_contents(pkg, input_root, filter=ignore_files)

    # Now actually merge them.
    for entry in contents:
        if entry[0] == 'obj':
            path = entry[1].lstrip('/')
            output = os.path.join(output_root, path)
            if verbose:
                print('>>> %s' % path)
            else:
                print('.', end='')
            makedirs(os.path.dirname(output))
            shutil.copy2(os.path.join(input_root, path), output)
        elif entry[0] == 'sym':
            path = entry[1].lstrip('/')
            target = entry[2]
            output = os.path.join(output_root, path)
            if verbose:
                print('>>> %s -> %s' % (path, target))
            else:
                print('.', end='')
            unlink(output)
            makedirs(os.path.dirname(output))
            os.symlink(target, output)
        else:
            raise Exception('Unhandled entry: %r' % entry)

    make_target = os.path.join(make_root, pkg + '.emerge')
    makedirs(os.path.dirname(make_target))
    open(make_target, 'w')

    if not verbose:
        print('')


def get_parser():
    """Return a command line parser."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('-p', '--package', action='append', required=True,
                        dest='packages',
                        help='Merge these package(s)')
    parser.add_argument('--input-root', type=str, required=True,
                        help='Where to read the packages')
    parser.add_argument('--output-root', type=str, required=True,
                        help='Where to write the packages')
    parser.add_argument('--make-root', type=str, required=True,
                        help='Where make writes state files for rules')
    parser.add_argument('-v', '--verbose', action='count',
                        help='Make output more verbose')
    return parser


def main(argv):
    parser = get_parser()
    opts = parser.parse_args(argv)

    for pkg in opts.packages:
        merge(pkg, opts.input_root, opts.output_root, opts.make_root,
              verbose=opts.verbose)


if __name__ == '__main__':
    main(sys.argv[1:])
