#!/usr/bin/env python2.7
# 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"
    }
  }

It also tests for conflicts in the 'diagnostics' key.

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

  data/some_package/foo=../../src/somewhere/foo
  data/sysmgr/services.config=../../src/sys/sysmgr/config/services.config
  data/sysmgr/file1.config=../../src/bar/file1.config
  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).
"""

import argparse
import json
import os
import sys


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--stamp', metavar='FILE', help='Touch FILE at the end.', required=True)
    parser.add_argument(
        '--depfile',
        metavar='FILE',
        help='Write a GN depfile to the given path',
        required=True)
    parser.add_argument('manifest', help='config-data package manifest')
    args = parser.parse_args()

    with open(args.manifest, 'r') as f:
        lines = f.read().splitlines()

    # Build a list of all the source paths that contribute to sysmgr's config-data
    sysmgr_lines = [line for line in lines if line.startswith('data/sysmgr/')]
    sysmgr_config_files = [line.split('=')[1] for line in sysmgr_lines]

    # Parse all config files and 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.
    seen_services = {}
    service_conflicts = {}
    seen_diag = None
    diag_conflicts = []
    for config_file in sysmgr_config_files:
        with open(config_file, 'r') as f:
            config = json.load(f)

        diag = config.get('diagnostics')
        if diag is not None:
            if seen_diag is None:
                seen_diag = config_file
            else:
                if not diag_conflicts:
                    diag_conflicts.append(seen_diag)
                diag_conflicts.append(config_file)

        services = config.get('services')
        if not services:
            continue
        for service in services.iterkeys():
            if service in seen_services:
                if not service in service_conflicts:
                    service_conflicts[service] = [seen_services[service]]
                service_conflicts[service].append(config_file)
            else:
                seen_services[service] = config_file

    # If any conflicts were detected, print a useful error message and then
    # exit.
    if service_conflicts or diag_conflicts:
        print('Error: conflicts detected in sysmgr configuration')
        for service, config_files in service_conflicts.items():
            print(
                'Duplicate configuration for service {} in files: {}'.format(
                    service, ', '.join(config_files)))
        if diag_conflicts:
            print(
                'Duplicate diagnostics config in files: {}'.format(
                    ', '.join(diag_conflicts)))
        return 1

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

    # Write the stampfile.
    with open(args.stamp, 'w') as f:
        os.utime(f.name, None)

    return 0


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