#!/usr/bin/env python
#
# Copyright 2019 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Writes Java module descriptor to srcjar file."""

import argparse
import os
import sys
import zipfile

sys.path.append(
    os.path.join(
        os.path.dirname(__file__), "..", "..", "..", "build"))
import action_helpers
import zip_helpers

_TEMPLATE = """\
// This file is autogenerated by
//     components/module_installer/android/module_desc_java.py
// Please do not change its content.

package org.chromium.components.module_installer.builder;

import org.chromium.build.annotations.UsedByReflection;

@UsedByReflection("Module.java")
public class ModuleDescriptor_{MODULE} implements ModuleDescriptor {{
    private static final String[] PAKS = {{{PAKS}}};

    @UsedByReflection("Module.java")
    public ModuleDescriptor_{MODULE}() {{}}

    @Override
    public String[] getPaks() {{
        return PAKS;
    }}

    @Override
    public boolean getLoadNativeOnGetImpl() {{
        return {LOAD_NATIVE_ON_GET_IMPL};
    }}
}}
"""


def main():
    parser = argparse.ArgumentParser()
    action_helpers.add_depfile_arg(parser)
    parser.add_argument('--module', required=True, help='The module name.')
    parser.add_argument('--libraries-file',
                        required=True,
                        help='Path to file with GN list of library paths')
    parser.add_argument('--paks', help='GN list of PAK file paths')
    parser.add_argument(
        '--output', required=True, help='Path to the generated srcjar file.')
    parser.add_argument('--load-native-on-get-impl', action='store_true',
        default=False,
        help='Load module automatically on calling Module.getImpl().')
    options = parser.parse_args()
    options.paks = action_helpers.parse_gn_list(options.paks)

    with open(options.libraries_file) as f:
        libraries_list = action_helpers.parse_gn_list(f.read())

    libraries = []
    for path in libraries_list:
        path = path.strip()
        filename = os.path.split(path)[1]
        assert filename.startswith('lib')
        assert filename.endswith('.so')
        # Remove lib prefix and .so suffix.
        libraries += [filename[3:-3]]
    paks = options.paks if options.paks else []

    format_dict = {
        'MODULE': options.module,
        'LIBRARIES': ','.join(['"%s"' % l for l in libraries]),
        'PAKS': ','.join(['"%s"' % os.path.basename(p) for p in paks]),
        'LOAD_NATIVE_ON_GET_IMPL': (
            'true' if options.load_native_on_get_impl else 'false'),
    }
    with action_helpers.atomic_output(options.output) as f:
        with zipfile.ZipFile(f.name, 'w') as srcjar_file:
            zip_path = (f'org/chromium/components/module_installer/builder/'
                        f'ModuleDescriptor_{options.module}.java')
            zip_helpers.add_to_zip_hermetic(
                srcjar_file, zip_path,
                data=_TEMPLATE.format(**format_dict))

    if options.depfile:
        action_helpers.write_depfile(options.depfile,
                                     options.output,
                                     inputs=[options.libraries_file])


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