#!/usr/bin/env python
#
# Copyright (C) 2020 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 tool to convert json file into pb with linker config format."""

import argparse
import collections
import json
import os

import linker_config_pb2 #pylint: disable=import-error
from google.protobuf.descriptor import FieldDescriptor
from google.protobuf.json_format import ParseDict
from google.protobuf.text_format import MessageToString


def Proto(args):
    pb = linker_config_pb2.LinkerConfig()
    if args.source:
        for input in args.source.split(':'):
            json_content = ''
            with open(input) as f:
                for line in f:
                    if not line.lstrip().startswith('//'):
                        json_content += line
            obj = json.loads(json_content, object_pairs_hook=collections.OrderedDict)
            ParseDict(obj, pb)
    with open(args.output, 'wb') as f:
        f.write(pb.SerializeToString())


def Print(args):
    with open(args.source, 'rb') as f:
        pb = linker_config_pb2.LinkerConfig()
        pb.ParseFromString(f.read())
    print(MessageToString(pb))


def SystemProvide(args):
    pb = linker_config_pb2.LinkerConfig()
    with open(args.source, 'rb') as f:
        pb.ParseFromString(f.read())
    libraries = args.value.split()

    def IsInLibPath(lib_name):
        lib_path = os.path.join(args.system, 'lib', lib_name)
        lib64_path = os.path.join(args.system, 'lib64', lib_name)
        return os.path.exists(lib_path) or os.path.islink(
            lib_path) or os.path.exists(lib64_path) or os.path.islink(
                lib64_path)

    installed_libraries = [lib for lib in libraries if IsInLibPath(lib)]
    for item in installed_libraries:
        if item not in getattr(pb, 'provideLibs'):
            getattr(pb, 'provideLibs').append(item)
    with open(args.output, 'wb') as f:
        f.write(pb.SerializeToString())


def Append(args):
    pb = linker_config_pb2.LinkerConfig()
    with open(args.source, 'rb') as f:
        pb.ParseFromString(f.read())

    if getattr(type(pb),
               args.key).DESCRIPTOR.label == FieldDescriptor.LABEL_REPEATED:
        for value in args.value.split():
            getattr(pb, args.key).append(value)
    else:
        setattr(pb, args.key, args.value)

    with open(args.output, 'wb') as f:
        f.write(pb.SerializeToString())


def Merge(args):
    pb = linker_config_pb2.LinkerConfig()
    for other in args.input:
        with open(other, 'rb') as f:
            pb.MergeFromString(f.read())

    with open(args.out, 'wb') as f:
        f.write(pb.SerializeToString())


def GetArgParser():
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers()

    parser_proto = subparsers.add_parser(
        'proto',
        help='Convert the input JSON configuration file into protobuf.')
    parser_proto.add_argument(
        '-s',
        '--source',
        nargs='?',
        type=str,
        help='Colon-separated list of linker configuration files in JSON.')
    parser_proto.add_argument(
        '-o',
        '--output',
        required=True,
        type=str,
        help='Target path to create protobuf file.')
    parser_proto.set_defaults(func=Proto)

    print_proto = subparsers.add_parser(
        'print', help='Print configuration in human-readable text format.')
    print_proto.add_argument(
        '-s',
        '--source',
        required=True,
        type=str,
        help='Source linker configuration file in protobuf.')
    print_proto.set_defaults(func=Print)

    system_provide_libs = subparsers.add_parser(
        'systemprovide',
        help='Append system provide libraries into the configuration.')
    system_provide_libs.add_argument(
        '-s',
        '--source',
        required=True,
        type=str,
        help='Source linker configuration file in protobuf.')
    system_provide_libs.add_argument(
        '-o',
        '--output',
        required=True,
        type=str,
        help='Target linker configuration file to write in protobuf.')
    system_provide_libs.add_argument(
        '--value',
        required=True,
        type=str,
        help='Values of the libraries to append. If there are more than one '
        'it should be separated by empty space'
    )
    system_provide_libs.add_argument(
        '--system', required=True, type=str, help='Path of the system image.')
    system_provide_libs.set_defaults(func=SystemProvide)

    append = subparsers.add_parser(
        'append', help='Append value(s) to given key.')
    append.add_argument(
        '-s',
        '--source',
        required=True,
        type=str,
        help='Source linker configuration file in protobuf.')
    append.add_argument(
        '-o',
        '--output',
        required=True,
        type=str,
        help='Target linker configuration file to write in protobuf.')
    append.add_argument('--key', required=True, type=str, help='.')
    append.add_argument(
        '--value',
        required=True,
        type=str,
        help='Values of the libraries to append. If there are more than one'
        'it should be separated by empty space'
    )
    append.set_defaults(func=Append)

    append = subparsers.add_parser('merge', help='Merge configurations')
    append.add_argument(
        '-o',
        '--out',
        required=True,
        type=str,
        help='Output linker configuration file to write in protobuf.')
    append.add_argument(
        '-i',
        '--input',
        nargs='+',
        type=str,
        help='Linker configuration files to merge.')
    append.set_defaults(func=Merge)

    return parser


def main():
    args = GetArgParser().parse_args()
    args.func(args)


if __name__ == '__main__':
    main()
