#!/usr/bin/env python3
# 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.
# Lint as: python3

import argparse
import re
import sys


# TODO(shayba): Make this more robust.
# * Actually parse cmx JSON / cml JSON5,
#   rather than match against formatted files with regular expressions.
# * Introduce more analysis that's aware of runners,
#   rather than bail out when any runners are involved.
#   Or maybe specialize the analysis,
#   for instance for Dart look for *.dlib files under program.data.
# * Validate more paths (data files/directories?)
#   rather than just binary paths.
def main():
    parser = argparse.ArgumentParser(
        'Validate component manifests against package manifests')
    parser.add_argument(
        '--component_manifest',
        required=True,
        type=argparse.FileType('r'),
        help='Path to a component manifest to validate (cmx/cml file)')
    parser.add_argument(
        '--package_manifest',
        required=True,
        type=argparse.FileType('r'),
        help='Path to a package manifest to validate against')
    parser.add_argument(
        '--gn-label',
        required=True,
        help='GN label to include in error messages')
    parser.add_argument(
        '--stamp',
        required=True,
        type=argparse.FileType('w'),
        help='Stamp file')
    args = parser.parse_args()

    dsts = [
        dst for dst, _, src in (
            line.partition('=') for line in args.package_manifest.readlines())
    ]

    # Suppression marker
    allow_invalid_program_binary = "#[allow(invalid_program_binary)]"

    # These runners don't respect program.binary
    # fxbug.dev/67151 do something more sophisticated
    runners_to_avoid = [
        "appmgr_mock_runner.cmx",
        "guest_runner.cmx",
        "netemul-runner.cmx",
    ]

    # Matches program.binary in any formatted cmx or cml file
    binary_re = re.compile('        "?binary"?: "([^"]*)",?')
    binary_value = None
    for line in args.component_manifest.readlines():
        if allow_invalid_program_binary in line:
            return stamp(args)
        for runner in runners_to_avoid:
            if runner in line:
                return stamp(args)
        m = binary_re.match(line)
        if m:
            binary_value = m.group(1)

    if not binary_value:
        # Nothing to validate
        return stamp(args)

    if binary_value in dsts:
        return stamp(args)

    # Legacy package.gni supports the "disabled test" feature that intentionally
    # breaks component manifests. /shrug
    if binary_value.startswith(
            "test/") and "test/disabled/" + binary_value[5:] in dsts:
        return stamp(args)

    print(f'Error found in: {args.gn_label}')
    print(f'Failed to validate manifest: {args.component_manifest.name}')
    print(f'program.binary="{binary_value}" but {binary_value} is not in deps!')
    print()
    nearest = nearest_match(binary_value, dsts)
    if nearest:
        print(f'Did you mean "{nearest}"?')
        print()
    print('Try any of the following:')
    print('\n'.join(sorted(dsts)))
    return 1


def stamp(args):
    args.stamp.write('Success!')
    return 0


def nearest_match(start, candidates):
    """Finds the nearest match to `start` out of `candidates`."""
    nearest = None
    min_distance = sys.maxsize
    for candidate in candidates:
        distance = minimum_edit_distance(start, candidate)
        if distance < min_distance:
            min_distance = distance
            nearest = candidate
    return nearest


def minimum_edit_distance(s, t):
    """Finds the Levenshtein distance between `s` and `t`."""
    # Dynamic programming table
    rows = len(s) + 1
    cols = len(t) + 1
    dist = [[0 for x in range(cols)] for x in range(rows)]

    # Fastest way to transform to empty string is N deletions
    for i in range(1, rows):
        dist[i][0] = i
    # Fastest way to transform from empty string is N insertions
    for i in range(1, cols):
        dist[0][i] = i

    for col in range(1, cols):
        for row in range(1, rows):
            if s[row - 1] == t[col - 1]:
                cost = 0
            else:
                cost = 1
            dist[row][col] = min(
                dist[row - 1][col] + 1,  # Deletion
                dist[row][col - 1] + 1,  # Insertion
                dist[row - 1][col - 1] + cost)  # Substitution

    return dist[row][col]


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