#!/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.
"""Find disabled tests.

This script assumes that it's run in the root directory of a Fuchsia
checkout.
"""
# pylint: disable=consider-using-with,unspecified-encoding

import functools
import json
import os
import sys
import tempfile
import unittest
import re

RUST_EXT = "rs"
DART_EXT = "dart"
BUILD_EXT = "gn"
C_EXT = "cc"
TODO_ENABLE = re.compile(r"^(\/\/|\#).*(TODO).*(enable|disable).*(test|flake).*")
FXB_REGEX = re.compile(r"fxb.*\/(\d+)")
DISABLED_CC_TEST = "DISABLED_"

# Mapping language to method of disablement
DISABLED_FLAG_MAP = {
    C_EXT: DISABLED_CC_TEST,
}


def main():
    args = sys.argv[1:]
    tmp_json = args[0]
    curpath = os.path.abspath(os.path.curdir)
    disabled_tests = []

    exclude = set(["third_party"])
    for dirpath, dirs, files in os.walk(curpath):
        dirs[:] = [d for d in dirs if d not in exclude]
        for filename in files:
            fname = os.path.join(dirpath, filename)
            if fname.endswith((RUST_EXT, DART_EXT, BUILD_EXT, C_EXT)):
                file_ext = os.path.splitext(filename)[1]
                find_disabled_tests(fname, disabled_tests, curpath, file_ext)

    with open(tmp_json, "w") as f:
        json.dump(disabled_tests, f, indent=1, separators=(",", ": "))


def find_disabled_tests(file_path, disabled_tests, curpath, file_ext):
    with open(file_path) as f:
        for i, line in enumerate(f.readlines()):
            line = line.strip()
            # Check for TODO and language-specific flags signifying the test was disabled
            if TODO_ENABLE.match(line) or (
                file_ext in DISABLED_FLAG_MAP and DISABLED_FLAG_MAP[file_ext] in line
            ):
                bug = FXB_REGEX.search(line)
                disabled_tests.append(
                    {
                        "path": os.path.relpath(file_path, curpath),
                        "line_number": i + 1,
                        "bug": bug.group(1) if bug else "",
                        "compiled": file_ext is BUILD_EXT,
                    }
                )


class TestFindDisabledTest(unittest.TestCase):
    def setUp(self):
        self.tempdir = tempfile.TemporaryDirectory("find_disabled_tests")

    def test_basic_file(self):
        got = []
        path = os.path.join(self.tempdir.name, "test.cc")
        with open(path, "w") as f:
            f.write(
                "\n".join(
                    [
                        "// TODO(fxbug.dev/12345) re-enable this test when de-flaked",
                        "fn flaky_test_we_need_to_fix() { ... }",
                        "TEST_F(BlobfsTest, DISABLED_CorruptBlobNotify) { RunBlobCorruptionTest(); }",
                    ]
                )
            )
        find_disabled_tests(path, got, _)
        want = [
            {"path": path, "line_number": 1, "bug": "12345", "compiled": False},
            {"path": path, "line_number": 3, "bug": "", "compiled": False},
        ]
        self.assertEqual(got, want)

    def tearDown(self):
        self.tempdir.cleanup()


if __name__ == "__main__":
    main()
