// Copyright 2023 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/tint/sem/test_helper.h"

#include "src/tint/sem/module.h"

using namespace tint::number_suffixes;  // NOLINT

namespace tint::sem {
namespace {

class DiagnosticSeverityTest : public TestHelper {
  protected:
    /// Create a program with two functions, setting the severity for "chromium_unreachable_code"
    /// using an attribute. Test that we correctly track the severity of the filter for the
    /// functions and the statements with them.
    /// @param global_severity the global severity of the "chromium_unreachable_code" filter
    void Run(builtin::DiagnosticSeverity global_severity) {
        // @diagnostic(off, chromium_unreachable_code)
        // fn foo() {
        //   @diagnostic(info, chromium_unreachable_code) {
        //     @diagnostic(error, chromium_unreachable_code)
        //     if (true) @diagnostic(warning, chromium_unreachable_code) {
        //       return;
        //     } else if (false) {
        //       return;
        //     } else @diagnostic(info, chromium_unreachable_code) {
        //       return;
        //     }
        //     return;
        //
        //     @diagnostic(error, chromium_unreachable_code)
        //     switch (42) {
        //       case 0 @diagnostic(warning, chromium_unreachable_code) {
        //         return;
        //       }
        //       default {
        //         return;
        //       }
        //     }
        //
        //     @diagnostic(error, chromium_unreachable_code)
        //     for (var i = 0; false; i++) @diagnostic(warning, chromium_unreachable_code) {
        //       return;
        //     }
        //   }
        //
        //     @diagnostic(error, chromium_unreachable_code)
        //     while (false) @diagnostic(warning, chromium_unreachable_code) {
        //       return;
        //     }
        //   }
        // }
        //
        // fn bar() {
        //   return;
        // }
        auto rule = builtin::DiagnosticRule::kChromiumUnreachableCode;
        auto func_severity = builtin::DiagnosticSeverity::kOff;
        auto block_severity = builtin::DiagnosticSeverity::kInfo;
        auto if_severity = builtin::DiagnosticSeverity::kError;
        auto if_body_severity = builtin::DiagnosticSeverity::kWarning;
        auto else_body_severity = builtin::DiagnosticSeverity::kInfo;
        auto switch_severity = builtin::DiagnosticSeverity::kError;
        auto case_severity = builtin::DiagnosticSeverity::kWarning;
        auto for_severity = builtin::DiagnosticSeverity::kError;
        auto for_body_severity = builtin::DiagnosticSeverity::kWarning;
        auto while_severity = builtin::DiagnosticSeverity::kError;
        auto while_body_severity = builtin::DiagnosticSeverity::kWarning;
        auto attr = [&](auto severity) {
            return utils::Vector{DiagnosticAttribute(severity, "chromium_unreachable_code")};
        };

        auto* return_foo_if = Return();
        auto* return_foo_elseif = Return();
        auto* return_foo_else = Return();
        auto* return_foo_block = Return();
        auto* return_foo_case = Return();
        auto* return_foo_default = Return();
        auto* return_foo_for = Return();
        auto* return_foo_while = Return();
        auto* else_stmt = Block(utils::Vector{return_foo_else}, attr(else_body_severity));
        auto* elseif = If(Expr(false), Block(return_foo_elseif), Else(else_stmt));
        auto* if_foo = If(Expr(true), Block(utils::Vector{return_foo_if}, attr(if_body_severity)),
                          Else(elseif), attr(if_severity));
        auto* case_stmt =
            Case(CaseSelector(0_a), Block(utils::Vector{return_foo_case}, attr(case_severity)));
        auto* swtch = Switch(42_a, utils::Vector{case_stmt, DefaultCase(Block(return_foo_default))},
                             attr(switch_severity));
        auto* fl =
            For(Decl(Var("i", ty.i32())), false, Increment("i"),
                Block(utils::Vector{return_foo_for}, attr(for_body_severity)), attr(for_severity));
        auto* wl = While(false, Block(utils::Vector{return_foo_while}, attr(while_body_severity)),
                         attr(while_severity));
        auto* block_1 =
            Block(utils::Vector{if_foo, return_foo_block, swtch, fl, wl}, attr(block_severity));
        auto* func_attr = DiagnosticAttribute(func_severity, "chromium_unreachable_code");
        auto* foo = Func("foo", {}, ty.void_(), utils::Vector{block_1}, utils::Vector{func_attr});

        auto* return_bar = Return();
        auto* bar = Func("bar", {}, ty.void_(), utils::Vector{return_bar});

        auto p = Build();
        EXPECT_TRUE(p.IsValid()) << p.Diagnostics().str();

        EXPECT_EQ(p.Sem().DiagnosticSeverity(foo, rule), func_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(block_1, rule), block_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(if_foo, rule), if_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(if_foo->condition, rule), if_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(if_foo->body, rule), if_body_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(return_foo_if, rule), if_body_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(elseif, rule), if_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(elseif->condition, rule), if_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(elseif->body, rule), if_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(return_foo_elseif, rule), if_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(else_stmt, rule), else_body_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(return_foo_else, rule), else_body_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(swtch, rule), switch_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(swtch->condition, rule), switch_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(case_stmt, rule), switch_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(case_stmt->body, rule), case_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(return_foo_case, rule), case_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(return_foo_default, rule), switch_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(fl, rule), while_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(fl->initializer, rule), for_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(fl->condition, rule), for_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(fl->continuing, rule), for_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(fl->body, rule), for_body_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(return_foo_for, rule), for_body_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(wl, rule), while_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(wl->condition, rule), while_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(wl->body, rule), while_body_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(return_foo_while, rule), while_body_severity);

        EXPECT_EQ(p.Sem().DiagnosticSeverity(bar, rule), global_severity);
        EXPECT_EQ(p.Sem().DiagnosticSeverity(return_bar, rule), global_severity);
    }
};

TEST_F(DiagnosticSeverityTest, WithDirective) {
    DiagnosticDirective(builtin::DiagnosticSeverity::kError, "chromium_unreachable_code");
    Run(builtin::DiagnosticSeverity::kError);
}

TEST_F(DiagnosticSeverityTest, WithoutDirective) {
    Run(builtin::DiagnosticSeverity::kWarning);
}

}  // namespace
}  // namespace tint::sem
