# Copyright 2022 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.
"""
Test to prevent integrators from having future breakages caused
by instability of the Fuchsia SDK package directory.
"""

import argparse
import os
import sys
import tarfile
import re
from pathlib import Path


class GoldenFileGenerationError(Exception):
    """Exception raised when the SDK Tarball input
    contains a file which is not a regular file or directory."""

    def __init__(self, tarfile, invalid):
        self.tarfile = tarfile
        self.invalid = invalid

    def __str__(self):
        return (
            f"Detected invalid file within the SDK archive "
            f"tarfile:\n{self.invalid}\n"
            f"Golden file will not be generated if the tarfile contains this file type.\n"
            f"Please update\n"
            f" {self.tarfile}\n"
            f" accordingly.\n"
            f"If you're seeing this in CQ but not in your local build, you will need\n"
            f" to rebuild locally with the same CPU architecture (x64/arm64) as this\n"
            f" builder and add '//sdk/ctf:verify_idk_deps' into your local build args.\n")


class MissingInputError(Exception):
    """Exception raised when a missing golden file
    or current archive tarball is detected."""

    def __init__(self, missing, is_tar=False, stamp=False):
        self.missing = missing
        self.is_tar = is_tar
        self.stamp = stamp

    def __str__(self):
        input = "golden file"
        if self.is_tar:
            input = "current archive tarball"
        elif self.stamp:
            input = "verification file path"
        return_str = f"The {input} appears to be missing:\n{self.missing}\n"
        if not (self.is_tar or self.stamp):
            return_str += (
                f"Please consult with sdk-dev@fuchsia.dev to"
                f" locate and resolve this missing golden file.\n")
        return return_str


class NotifyOnAdditions(Exception):
    """Exception raised to notify developers of non-breaking changes.

    Args:
        idk: SDK archive tarball dependency target name.
        additions: Paths found in the archive but not in the golden file.
        path: Path to create a temporary golden file for the archive.
        golden: Path to the golden file.
    """

    def __init__(self, idk, additions, path, golden):
        self.idk = idk
        self.additions = additions
        self.path = path
        self.golden = golden

    def __str__(self):
        cmd = update_golden(self.path, self.golden)
        return (
            f"Detected additions to the {self.idk} SDK's directory layout.\n"
            f"The current archive tarball contains these additional "
            f"paths not found in the golden file.\n{self.additions}\n"
            f"If this is an intentional change, follow the instructions"
            f" below based on where you encountered this message:\n"
            f"  - in CQ: rebuild locally with the same CPU architecture (x64/arm64)\n"
            f"           as this builder and add '//sdk/ctf:verify_idk_deps' into\n"
            f"           your local build args.\n"
            f"  - in your local build: run the following command: {cmd}\n")


class SdkCompatibilityError(Exception):
    """Exception raised when breaking changes are detected.

    Args:
        idk: SDK archive tarball dependency target name.
        missing_goldens: Paths expected to be in the archive, but not found.
        path: Path to create a temporary golden file for the archive.
        golden: Path to the golden file.
    """

    def __init__(self, idk, missing_goldens, path, golden):
        self.idk = idk
        self.missing_goldens = missing_goldens
        self.path = path
        self.golden = golden

    def __str__(self):
        cmd = update_golden(self.path, self.golden)
        return (
            f"Detected breaking changes to the {self.idk} SDK's directory layout.\n"
            f"If possible, please make a soft transition"
            f" to prevent breaking SDK users.\nThe following paths are missing"
            f" from the SDK:\n{self.missing_goldens}\n"
            f"If you have approval to make this change, follow the instructions"
            f" below based on where you encountered this message:\n"
            f"  - in CQ: rebuild locally with the same CPU architecture (x64/arm64)\n"
            f"           as this builder and add '//sdk/ctf:verify_idk_deps' into\n"
            f"           your local build args.\n"
            f"  - in your local build: run the following command: {cmd}\n")


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--golden', help='Path to the golden file')
    parser.add_argument(
        '--current', help='Path to the SDK archive tarball', required=True)
    parser.add_argument('--stamp', help='Verification output file path')
    parser.add_argument(
        '--generate_golden',
        help='Generate SDK directory layout golden file.',
        action='store_true')
    parser.add_argument(
        '--gen_golden_path',
        help='Path to generate SDK directory layout golden file.')
    parser.add_argument(
        '--update_golden',
        help='Path to the updated golden file for when changes are made.')
    parser.add_argument(
        '--warn_only', help='Treat failures as warnings', action='store_true')
    args = parser.parse_args()

    err = None
    notify = None
    if args.generate_golden:
        try:
            golden_sdk_set = generate_sdk_layout_golden_file(args.current)
        except (MissingInputError, GoldenFileGenerationError) as e:
            err = e
        golden_sdk_layout = sorted(golden_sdk_set)
        try:
            with open(args.gen_golden_path, 'w') as golden_sdk_layout_file:
                layout = "{}\n".format("\n".join(golden_sdk_layout or []))
                golden_sdk_layout_file.write(layout)
        except FileNotFoundError:
            err = str(MissingInputError(missing=args.gen_golden_path))
    else:
        try:
            fail_on_breaking_changes(
                args.current, args.golden, args.update_golden)
        except (SdkCompatibilityError, MissingInputError) as e:
            err = e
        except NotifyOnAdditions as n:
            notify = n
        try:
            with open(args.stamp, 'w') as stamp_file:
                stamp_file.write('Verified!\n')
        except FileNotFoundError:
            err = str(MissingInputError(missing=args.stamp, stamp=True))

    if not (err or notify):
        return 0
    elif notify:
        print("NOTICE: ", notify)
    else:
        print("ERROR: ", err)
    return 0 if args.warn_only else 1


def fail_on_breaking_changes(current_archive, golden_file, update_golden):
    """Fails if current is not compatible with golden."""

    gold_set = set()
    try:
        with open(golden_file, 'r') as gold_lines:
            for line in gold_lines:
                gold_set.add(line.strip())
    except FileNotFoundError:
        raise MissingInputError(missing=golden_file, is_tar=False)

    curr_set = generate_sdk_layout_golden_file(current_archive)

    set_diff = gold_set.difference(curr_set)

    # See if any golden paths are not in the current archive.
    if len(set_diff) != 0:
        raise SdkCompatibilityError(
            idk=Path(current_archive).with_suffix('').stem,
            missing_goldens=set_diff,
            path=update_golden,
            golden=golden_file)

    # Notify developer of any additions to the SDK directory layout.
    if len(gold_set) != len(curr_set):
        raise NotifyOnAdditions(
            idk=Path(current_archive).with_suffix('').stem,
            additions=curr_set.difference(gold_set),
            path=update_golden,
            golden=golden_file)
    return None


def generate_sdk_layout_golden_file(current_archive):
    try:
        with tarfile.open(current_archive, "r:gz") as sdk_file:
            layout = sdk_file.getmembers()
    except (tarfile.ReadError, FileNotFoundError):
        raise MissingInputError(missing=current_archive, is_tar=True)

    # Ignore golden file checks for paths ending in .debug as they change frequently.
    path_regex = "\.build-id" + re.escape(os.sep) + "\w{2}" + re.escape(
        os.sep) + "\w{14}\.debug"
    ignored_path = re.compile(path_regex, re.IGNORECASE)

    # If directories in the list below exist, they're added to the set of golden paths.
    # Files in such directories will not be compatibility tested.
    dirs_exist = [
        os.path.join('tools', 'x64', 'aemu_internal', ''),
        os.path.join('tools', 'x64', 'qemu_internal', ''),
    ]

    golden_set = set()
    for path in layout:
        if ignored_path.match(path.name):
            continue
        # Set to True if the file in question is not going to be compatibility tested.
        ignoring_file = False

        # Add the directory into the golden set if it exists.
        for dir in dirs_exist:
            if path.name.startswith(dir):
                golden_set.add(dir)
                ignoring_file = True
                break
        if ignoring_file:
            continue

        gold_dir = path.name
        if path.isdir() and not path.name.endswith(os.sep):
            # Ensure directory type paths end in a "/".
            gold_dir += os.sep
        elif not (path.isfile() or path.isdir()):
            raise GoldenFileGenerationError(
                tarfile=current_archive, invalid=path)
        golden_set.add(gold_dir)
    return golden_set


def update_golden(updated_path, golden):
    """For presentation only. Never execute the cmd output programmatically because
    it may present a security exploit."""
    return "cp \"{}\" \"{}\"".format(
        os.path.abspath(updated_path), os.path.abspath(golden))


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