#!/usr/bin/env fuchsia-vendored-python
#
# Copyright 2016 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Make a mapping of dependencies for fidl files.

The map contains one line per mapping, each of which is from a fidl file location
to a sequence of GN build targets. If the mapping is public (ie directly from the
source or through a public_deps dependency) then it is prepended with "pub ".

The sequence of targets has length greater than 1 if the file can be referenced
from this module through a sequence of dependencies.

An example entry is:

pub //garnet/public/lib/ui/views/fidl/views.fidl: //garnet/public/lib/media/fidl:services //garnet/public/lib/ui/base_view/cpp:cpp
"""

import ast
import optparse
import os
import sys
import zipfile


# for some reason, gn seems to tack on an extra element in the directory
def fix_label(label):
    split_tag = label.split(':')
    split_label = split_tag[0].split('/')
    split_label.pop()
    split_tag[0] = '/'.join(split_label)
    return ':'.join(split_tag)


def rel_label(label, relpath):
    split_label = label.split(':')[0].split('/')
    for el in relpath.split('/'):
        if el == '..':
            split_label.pop()
        else:
            split_label.append(el)
    return '/'.join(split_label)


def handle_map_deps(o, depsmap, covered, target, is_public):
    #o.write('#pass-through from %s (public %s)\n' % (depsmap, is_public))
    for dep in file(depsmap):
        parts = dep.split()
        if parts[0] != 'pub':
            continue
        fileref = parts[1].rstrip(':')
        if fileref in covered:
            continue
        pubstr = 'pub ' if is_public else ''
        o.write(
            '%s%s: %s %s\n' % (pubstr, fileref, target, ' '.join(parts[2:])))


def make_map(output, sources, map_deps, map_public_deps, target):
    target = fix_label(target)
    o = file(output, 'w')
    covered = set()
    for i in sources:
        covered.add(i)
        new_path = rel_label(target, i)
        o.write('pub %s: %s\n' % (new_path, target))
    for m in map_deps:
        handle_map_deps(o, m, covered, target, False)
    for m in map_public_deps:
        handle_map_deps(o, m, covered, target, True)


def main():
    parser = optparse.OptionParser()

    parser.add_option('--sources', help='List of source files.')
    parser.add_option('--target', help='Name of current target.')
    parser.add_option(
        '--map-deps', help='List of map files of deps to aggregate.')
    parser.add_option(
        '--map-public-deps',
        help='List of map files of public deps to aggregate.')
    parser.add_option('--output', help='Path to output archive.')

    options, _ = parser.parse_args()

    sources = []
    if (options.sources):
        sources = ast.literal_eval(options.sources)
    map_deps = []
    if options.map_deps:
        map_deps = ast.literal_eval(options.map_deps)
    map_public_deps = []
    if options.map_public_deps:
        map_public_deps = ast.literal_eval(options.map_public_deps)
    output = options.output
    target = options.target

    make_map(output, sources, map_deps, map_public_deps, target)


if __name__ == '__main__':
    sys.exit(main())
