#!/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.

import argparse
import dataclasses
import os
import shlex
import subprocess
import sys
from typing import FrozenSet, Iterable, Sequence, Tuple


def check_access_line(
        op: str, path: str, allowed_reads: FrozenSet[str],
        allowed_writes: FrozenSet[str]) -> Sequence[Tuple[str, str]]:
    """Validates a file system access against a set of allowed accesses.

    Args:
      op: operation code in [rwdtm]
        See: https://github.com/jacereda/fsatrace#output-format
      path: file(s) accessed.
        Only the 'm' move operation contains two paths: "destination|source".
      allowed_reads: set of allowed read paths.
      allowed_writes: set of allowed write paths.

    Returns:
      0 to 2 access violations in the form (op, path).
    """
    if op == "r":
        if path not in allowed_reads:
            return [("read", path)]
    elif op in {"w", "d", "t"}:
        if path not in allowed_writes:
            return [("write", path)]
    elif op == "m":
        # path: "destination|source" (both are considered writes)
        return [
            ("write", path)
            for path in path.split("|")
            if path not in allowed_writes
        ]
    return []


@dataclasses.dataclass
class AccessTraceChecker(object):
    """Validates a sequence of file system accesses against constraints.
    """

    # Accesses outside of this path prefix are not checked.
    # An empty string will cause the checker to validate all accesses.
    required_path_prefix: str = ""

    # These affixes will be ignored for read/write checks.
    ignored_prefixes: FrozenSet[str] = dataclasses.field(default_factory=set)
    ignored_suffixes: FrozenSet[str] = dataclasses.field(default_factory=set)
    ignored_path_parts: FrozenSet[str] = dataclasses.field(default_factory=set)

    # These are explicitly allowed accesses that are checked once the
    # above criteria are met.
    allowed_reads: FrozenSet[str] = dataclasses.field(default_factory=set)
    allowed_writes: FrozenSet[str] = dataclasses.field(default_factory=set)

    def check_accesses(self,
                       accesses: Iterable[str]) -> Sequence[Tuple[str, str]]:
        """Checks a sequence of access against constraints.

        Accesses outside of required_path_prefix are ignored.
        Accesses to paths that match any of the ignored_* properties will be ignored.
        All other accesses are checked against allowed_reads and allowed_writes.

        Args:
          accesses: lines in fsatrace output format.
            See: https://github.com/jacereda/fsatrace#output-format
            The sequence of accesses matters when tracking moves.

        Returns:
          access violations (in the order they were encountered)
        """
        unexpected_accesses = []
        for access in accesses:
            op, sep, path = access.partition("|")
            if not sep == "|":
                # Not a trace line, ignore
                continue
            if not path.startswith(self.required_path_prefix):
                # Outside of root, ignore
                continue
            if any(path.startswith(ignored)
                   for ignored in self.ignored_prefixes):
                continue
            if any(path.endswith(ignored) for ignored in self.ignored_suffixes):
                continue
            if any(part for part in path.split(os.path.sep)
                   if part in self.ignored_path_parts):
                continue
            unexpected_accesses.extend(
                check_access_line(
                    op, path, self.allowed_reads, self.allowed_writes))

        # TODO(fangism): check for missing must_write accesses
        # TODO(fangism): track state of files across moves
        return unexpected_accesses


def main():
    parser = argparse.ArgumentParser(
        description="Traces a GN action and enforces strict inputs/outputs",
        argument_default=[],
    )
    parser.add_argument(
        "--label", required=True, help="The wrapped target's label")
    parser.add_argument(
        "--trace-output", required=True, help="Where to store the trace")
    parser.add_argument(
        "--target-type",
        choices=["action", "action_foreach"],
        default="action",
        help="Type of target being wrapped",
    )
    parser.add_argument("--script", required=True, help="action#script")
    parser.add_argument("--response-file-name", help="action#script")
    parser.add_argument("--inputs", nargs="*", help="action#inputs")
    parser.add_argument("--sources", nargs="*", help="action#sources")
    parser.add_argument("--outputs", nargs="*", help="action#outputs")
    parser.add_argument("--depfile", help="action#depfile")
    parser.add_argument("args", nargs="*", help="action#args")
    args = parser.parse_args()

    # Ensure trace_output directory exists
    trace_output_dir = os.path.dirname(args.trace_output)
    os.makedirs(trace_output_dir, exist_ok=True)

    # TODO(shayba): make this work without assuming `fsatrace` in path
    retval = subprocess.call(
        ["fsatrace", "rwmdt", args.trace_output, "--", args.script] + args.args)

    # If inner action failed that's a build error, don't bother with the trace.
    if retval != 0:
        return retval

    # Scripts with known issues
    # TODO(shayba): file bugs for the suppressions below
    ignored_scripts = [
        "sdk_build_id.py",
        # TODO(shayba): it's not the wrapper script that's the problem but some
        # of its usages. Refine the suppression or just fix the underlying
        # issues.
        "gn_script_wrapper.py",
        # When using `/bin/ln -f`, a temporary file may be created in the
        # target directory. This will register as a write to a non-output file.
        # TODO(shayba): address this somehow.
        "ln",
        # fxbug.dev/61771
        # "analysis_options.yaml",
    ]
    if os.path.basename(args.script) in ignored_scripts:
        return 0

    # `compiled_action()` programs with known issues
    # TODO(shayba): file bugs for the suppressions below
    ignored_compiled_actions = [
        # fxbug.dev/61770
        "banjo_bin",
        "strings_to_json",
    ]
    if args.script == "../../build/gn_run_binary.sh":
        if os.path.basename(args.args[1]) in ignored_compiled_actions:
            return 0

    # Paths that the action is allowed to access
    allowed_writes = {os.path.abspath(path) for path in args.outputs}

    depfile_outs = []
    depfile_ins = []
    if args.depfile:
        allowed_writes.add(os.path.abspath(args.depfile))
        with open(args.depfile, "r") as f:
            for line in f.read().strip().splitlines():
                out, _, ins = line.partition(":")
                depfile_outs.append(os.path.abspath(out))
                depfile_ins.extend(os.path.abspath(p) for p in shlex.split(ins))
        allowed_writes.update(depfile_ins)
        allowed_writes.update(depfile_outs)

    allowed_reads = {
        os.path.abspath(path)
        for path in [args.script] + args.inputs + args.sources + depfile_ins
    } | allowed_writes
    # TODO(fangism): prevent inputs from being written/touched/moved.
    # Changes to the input may confuse any timestamp-based build system,
    # and introduce race conditions among multiple reader rules.

    if args.response_file_name:
        allowed_reads.add(os.path.abspath(response_file_name))

    # Limit most access checks to files under src_root.
    src_root = os.path.dirname(os.path.dirname(os.getcwd()))

    # Paths that are ignored
    ignored_prefixes = {
        # Allow actions to access prebuilts that are not declared as inputs
        # (until we fix all instances of this)
        os.path.join(src_root, "prebuilt"),
    }
    ignored_suffixes = {
        # Allow actions to access Python code such as via imports
        # TODO(fangism): validate python imports under source control more precisely
        ".py",
        # TODO(shayba): remove hack below for response files
        #".rsp",
    }
    # TODO(fangism): for suffixes that we always ignore for writing, such as safe
    # or intended side-effect byproducts, make sure no declared inputs ever match them.
    ignored_path_parts = {
        # Python creates these directories with bytecode caches
        "__pycache__",
    }

    raw_trace = ""
    with open(args.trace_output, "r") as trace:
        raw_trace = trace.read()

    # Verify the filesystem access trace of the inner action
    checker = AccessTraceChecker(
        required_path_prefix=src_root,
        ignored_prefixes=ignored_prefixes,
        ignored_suffixes=ignored_suffixes,
        ignored_path_parts=ignored_path_parts,
        allowed_reads=allowed_reads,
        allowed_writes=allowed_writes)
    unexpected_accesses = checker.check_accesses(raw_trace.splitlines())

    if not unexpected_accesses:
        return 0

    accesses = "\n".join(f"{op} {path}" for (op, path) in unexpected_accesses)
    print(
        f"""
Unexpected file accesses building {args.label}, following the order they are accessed:
{accesses}

Full access trace:
{raw_trace}

See: https://fuchsia.dev/fuchsia-src/development/build/hermetic_actions

""",
        file=sys.stderr,
    )
    return 1


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