#!/usr/bin/env fuchsia-vendored-python
# 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.

"""
example:
find . \
    -path ./out -prune -o \
    -path ./garnet/public/lib/fidl/fuzz/input_corpus -prune -o \
    -path ./prebuilt -prune -o \
    -type f \
    -name \*.fidl -print0 \
  | xargs -0 tools/fidl/scripts/format_unions.py
"""

import sys

KW_REPLACEMENTS = [
    ("xunion", "flexible union"),
    ("union", "strict union"),
    ("strict xunion", "strict union"),
    # ('strict union', 'union')
]


def starts_with_oneof(s, prefixes):
    return any(s.startswith(p) for p in prefixes)


def format_file(path, in_place, format_lines):
    with open(path, "r+") as f:
        result = format_lines(f)

    if in_place:
        with open(path, "w") as f:
            f.writelines(result)
    else:
        print("".join(result))


def has_explicit_xunion(path):
    with open(path, "r") as f:
        in_union = False
        for line in f:
            if starts_with_oneof(line, ["xunion ", "strict xunion "]):
                in_union = True
            elif in_union and line.startswith("}"):
                in_union = False
            elif in_union and is_explicit(line.split()):
                return True
    return False


def purge_xunion(in_lines):
    out_lines = []
    for line in in_lines:
        for before, after in KW_REPLACEMENTS:
            if line.startswith(before):
                without_keyword = slice(len(before), None)
                updated = after + line[without_keyword]
                out_lines.append(updated)
                break
        else:
            out_lines.append(line)
    return out_lines


def add_explicit_ordinals(in_lines):
    out_lines = []
    current_union_lines = []
    in_union = False
    for line in in_lines:
        if starts_with_oneof(line, ["union ", "xunion ", "strict xunion "]):
            in_union = True
            out_lines.append(line)
        elif line.startswith("}") and in_union:
            out_lines += format_union_member_lines(current_union_lines)
            out_lines.append(line)
            current_union_lines = []
            in_union = False
        elif in_union:
            current_union_lines.append(line)
        else:
            out_lines.append(line)
    return out_lines


def format_union_member_lines(lines):
    out_lines = []
    ordinal_width = len(
        str(len([l for l in lines if is_union_field_line(l.split())]))
    )
    index = 1
    for line in lines:
        tokens = line.split()
        if not is_union_field_line(tokens):
            out_lines.append(line)
        elif is_explicit(tokens):
            out_lines.append(line)
        else:  # implicit, update to be explicit
            extra_spaces = (ordinal_width - len(str(index))) * " "
            indent = (len(line) - len(line.lstrip())) * " "
            out_lines.append(
                "{0}{1}{2}: {3}".format(
                    indent, extra_spaces, index, line.lstrip()
                )
            )
            index += 1
    return out_lines


def is_union_field_line(tokens):
    return not (
        not tokens or tokens[0].startswith("//") or tokens[0].startswith("[")
    )


def is_explicit(tokens):
    return tokens and tokens[0].endswith(":") and tokens[0][:-1].isnumeric()


def test():
    explicit_lines = [
        "    1: uint8 unused1;",
        "    2: uint8 unused2;",
        "    3: array<uint8>:6 variant;",
    ]
    print(format_union_member_lines(explicit_lines))

    implicit_lines = [
        "    uint32 before;",
        "    UnionSize12Alignment4 union;",
        "    uint32 after;",
    ]
    print(format_union_member_lines(implicit_lines))

    many_lines = [
        "    uint32 before;",
        "    UnionSize12Alignment4 union;",
        "    uint32 after;",
        "    uint32 before;",
        "    UnionSize12Alignment4 union;",
        "    uint32 after;",
        "    uint32 before;",
        "    UnionSize12Alignment4 union;",
        "    uint32 after;",
        "    uint32 before;",
        "    UnionSize12Alignment4 union;",
        "    uint32 after;",
    ]
    print(format_union_member_lines(many_lines))

    # doesn't currently work
    attribute_inline = [
        '   [Selector = "v2"] Foo foo;',
    ]
    print(format_union_member_lines(attribute_inline))


if __name__ == "__main__":
    for filename in sys.argv[1:]:
        try:
            format_file(filename, in_place=True, format_lines=purge_xunion)
            # if (has_explicit_xunion(filename)):
            #     print(filename)
        except:
            print("error in file: {0}".format(filename))
            raise
