// Copyright 2022 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/lang/wgsl/reader/parser/helper_test.h"

#include "src/tint/lang/wgsl/ast/discard_statement.h"

namespace tint::wgsl::reader {
namespace {

using WhileStmtTest = WGSLParserTest;

// Test an empty while loop.
TEST_F(WhileStmtTest, Empty) {
    auto p = parser("while true { }");
    Parser::AttributeList attrs;
    auto wl = p->while_statement(attrs);
    EXPECT_FALSE(p->has_error()) << p->error();
    EXPECT_FALSE(wl.errored);
    ASSERT_TRUE(wl.matched);
    EXPECT_TRUE(Is<ast::Expression>(wl->condition));
    EXPECT_TRUE(wl->body->Empty());
}

// Test an empty while loop with parentheses.
TEST_F(WhileStmtTest, EmptyWithParentheses) {
    auto p = parser("while (true) { }");
    Parser::AttributeList attrs;
    auto wl = p->while_statement(attrs);
    EXPECT_FALSE(p->has_error()) << p->error();
    EXPECT_FALSE(wl.errored);
    ASSERT_TRUE(wl.matched);
    EXPECT_TRUE(Is<ast::Expression>(wl->condition));
    EXPECT_TRUE(wl->body->Empty());
}

// Test a while loop with non-empty body.
TEST_F(WhileStmtTest, Body) {
    auto p = parser("while (true) { discard; }");
    Parser::AttributeList attrs;
    auto wl = p->while_statement(attrs);
    EXPECT_FALSE(p->has_error()) << p->error();
    EXPECT_FALSE(wl.errored);
    ASSERT_TRUE(wl.matched);
    EXPECT_TRUE(Is<ast::Expression>(wl->condition));
    ASSERT_EQ(wl->body->statements.Length(), 1u);
    EXPECT_TRUE(wl->body->statements[0]->Is<ast::DiscardStatement>());
}

// Test a while loop with complex condition.
TEST_F(WhileStmtTest, ComplexCondition) {
    auto p = parser("while (a + 1 - 2) == 3 { }");
    Parser::AttributeList attrs;
    auto wl = p->while_statement(attrs);
    EXPECT_FALSE(p->has_error()) << p->error();
    EXPECT_FALSE(wl.errored);
    ASSERT_TRUE(wl.matched);
    EXPECT_TRUE(Is<ast::BinaryExpression>(wl->condition));
    EXPECT_TRUE(wl->body->Empty());
}

// Test a while loop with complex condition, with parentheses.
TEST_F(WhileStmtTest, ComplexConditionWithParentheses) {
    auto p = parser("while ((a + 1 - 2) == 3) { }");
    Parser::AttributeList attrs;
    auto wl = p->while_statement(attrs);
    EXPECT_FALSE(p->has_error()) << p->error();
    EXPECT_FALSE(wl.errored);
    ASSERT_TRUE(wl.matched);
    EXPECT_TRUE(Is<ast::Expression>(wl->condition));
    EXPECT_TRUE(wl->body->Empty());
}

// Test a while loop with attributes.
TEST_F(WhileStmtTest, WithAttributes) {
    auto p = parser("@diagnostic(off, derivative_uniformity) while true { }");
    auto attrs = p->attribute_list();
    auto wl = p->while_statement(attrs.value);
    EXPECT_FALSE(p->has_error()) << p->error();
    EXPECT_FALSE(wl.errored);
    ASSERT_TRUE(wl.matched);

    EXPECT_TRUE(attrs->IsEmpty());
    ASSERT_EQ(wl->attributes.Length(), 1u);
    EXPECT_TRUE(wl->attributes[0]->Is<ast::DiagnosticAttribute>());
}

class WhileStmtErrorTest : public WGSLParserTest {
  public:
    void TestWhileWithError(std::string for_str, std::string error_str) {
        auto p_for = parser(for_str);
        Parser::AttributeList attrs;
        auto e_for = p_for->while_statement(attrs);

        EXPECT_FALSE(e_for.matched);
        EXPECT_TRUE(e_for.errored);
        EXPECT_TRUE(p_for->has_error());
        ASSERT_EQ(e_for.value, nullptr);
        EXPECT_EQ(p_for->error(), error_str);
    }
};

// Test a while loop with missing left parenthesis is invalid.
TEST_F(WhileStmtErrorTest, MissingLeftParen) {
    std::string while_str = "while bool) { }";
    std::string error_str = "1:11: expected '{' for while loop";

    TestWhileWithError(while_str, error_str);
}

// Test a while loop with missing condition is invalid.
TEST_F(WhileStmtErrorTest, MissingFirstSemicolon) {
    std::string while_str = "while () {}";
    std::string error_str = "1:8: unable to parse expression";

    TestWhileWithError(while_str, error_str);
}

// Test a while loop with missing right parenthesis is invalid.
TEST_F(WhileStmtErrorTest, MissingRightParen) {
    std::string while_str = "while (true {}";
    std::string error_str = "1:13: expected ')'";

    TestWhileWithError(while_str, error_str);
}

// Test a while loop with missing left brace is invalid.
TEST_F(WhileStmtErrorTest, MissingLeftBrace) {
    std::string while_str = "while (true) }";
    std::string error_str = "1:14: expected '{' for while loop";

    TestWhileWithError(while_str, error_str);
}

// Test a for loop with missing right brace is invalid.
TEST_F(WhileStmtErrorTest, MissingRightBrace) {
    std::string while_str = "while (true) {";
    std::string error_str = "1:15: expected '}' for while loop";

    TestWhileWithError(while_str, error_str);
}

// Test a while loop with an invalid break condition.
TEST_F(WhileStmtErrorTest, InvalidBreakConditionAsExpression) {
    std::string while_str = "while ((0 == 1) { }";
    std::string error_str = "1:17: expected ')'";

    TestWhileWithError(while_str, error_str);
}

// Test a while loop with a break condition not matching
// logical_or_expression.
TEST_F(WhileStmtErrorTest, InvalidBreakConditionMatch) {
    std::string while_str = "while (var i: i32 = 0) { }";
    std::string error_str = "1:8: unable to parse expression";

    TestWhileWithError(while_str, error_str);
}

// Test a while loop with an invalid body.
TEST_F(WhileStmtErrorTest, InvalidBody) {
    std::string while_str = "while (true) { let x: i32; }";
    std::string error_str = "1:26: expected '=' for 'let' declaration";

    TestWhileWithError(while_str, error_str);
}

// Test a for loop with a body not matching statements
TEST_F(WhileStmtErrorTest, InvalidBodyMatch) {
    std::string while_str = "while (true) { fn main() {} }";
    std::string error_str = "1:16: expected '}' for while loop";

    TestWhileWithError(while_str, error_str);
}

}  // namespace
}  // namespace tint::wgsl::reader
