#!/usr/bin/env python3.8
# Copyright 2020 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.
"""Validate the sysmgr config for the product being built.

Sysmgr's configuration is provided through the config-data package as a set of
JSON files, which are all individually read by sysmgr at runtime and merged to
form its overall configuration. This tool validates that there are no conflicts
between files, e.g. multiple files providing different component URLs for the
same "services" key. For example, it catches invalid configuration like this::


  file1.config:
  {
    "services": {
      "fuchsia.my.Service": "fuchsia-pkg://fuchsia.com/package_a#meta/foo.cmx"
    }
  }

  file2.config:
  {
    "services": {
      "fuchsia.my.Service": "fuchsia-pkg://fuchsia.com/package_b#meta/bar.cmx"
    }
  }

The input provided to this tool is expected to be the config-data package
manifest, formatted like this::

  meta/data/some_package/foo=../../src/somewhere/foo
  meta/data/sysmgr/services.config=../../src/sys/sysmgr/config/services.config
  meta/data/sysmgr/file1.config=../../src/bar/file1.config
  meta/data/other_package/baz=../../some/other/path/baz

where the path before the '=' is the destination path in the package, and the
path after the '=' is the source file (rebased to the root build directory).
"""

from collections import defaultdict
import argparse
import json
import os
import sys


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--depfile',
        type=argparse.FileType('w'),
        help='Write a GN depfile to the given path',
        required=True)
    parser.add_argument(
        '--merged',
        type=argparse.FileType('w'),
        help='Write a snapshot of this sysmgr config to the given path',
        required=True)
    parser.add_argument(
        '--config-entries',
        type=argparse.FileType('r'),
        help='config_data entries',
        required=True)
    args = parser.parse_args()

    # Build a list of all the source paths that contribute to sysmgr's config-data
    config_entries = json.load(args.config_entries)
    sysmgr_config_files = [
        e['source']
        for e in config_entries
        if e['destination'].startswith('meta/data/sysmgr/')
    ]

    # Parse all config files.
    #
    # Build a list of all conflicts, rather than
    # failing immediately on the first conflict. This allows us to print a more
    # useful build failure so that developers don't need to play whack-a-mole with
    # multiple conflicts.
    configs = []
    files_by_service = defaultdict(list)
    for config_file in sysmgr_config_files:
        with open(config_file, 'r') as f:
            config = json.load(f)
            configs.append(config)

            services = config.get('services')
            if services:
                for service in services.keys():
                    files_by_service[service].append(config_file)

    # If any conflicts were detected, print a useful error message and then
    # exit.
    service_conflicts = False
    for service, config_files in files_by_service.items():
        if len(config_files) > 1:
            print(
                'Duplicate sysmgr configuration for service {} in files: {}'.
                format(service, ', '.join(config_files)))
            service_conflicts = True

    if service_conflicts:
        return 1

    # Create a single merged configuration analogous to sysmgr's init itself.
    merged_config = {}
    for config in configs:
        for category, values in config.items():
            existing = merged_config.get(category)
            if type(existing) is dict:
                merged_config[category].update(values)
            elif type(existing) is list:
                merged_config[category] += values
            else:
                merged_config[category] = values

    json.dump(
        merged_config,
        args.merged,
        indent=2,
        separators=(',', ': '),
        sort_keys=True)

    # Write the depfile, which is a Makefile format file that has a single output
    # (the merged file) and lists all input files as dependencies.
    args.depfile.write(
        '{}: {}\n'.format(args.merged, ' '.join(sysmgr_config_files)))

    return 0


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