#!/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()
    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',
        required=True,
        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()
