//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#include "PreprocessorTest.h"
#include "Token.h"

class VersionTest : public PreprocessorTest
{
};

TEST_F(VersionTest, Valid)
{
    const char* str = "#version 200\n";
    const char* expected = "\n";

    using testing::_;
    EXPECT_CALL(mDirectiveHandler,
                handleVersion(pp::SourceLocation(0, 1), 200));
    // No error or warning.
    EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);

    preprocess(str, expected);
}

TEST_F(VersionTest, CommentsIgnored)
{
    const char* str = "/*foo*/"
                      "#"
                      "/*foo*/"
                      "version"
                      "/*foo*/"
                      "200"
                      "/*foo*/"
                      "//foo"
                      "\n";
    const char* expected = "\n";

    using testing::_;
    EXPECT_CALL(mDirectiveHandler,
                handleVersion(pp::SourceLocation(0, 1), 200));
    // No error or warning.
    EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);

    preprocess(str, expected);
}

TEST_F(VersionTest, MissingNewline)
{
    const char* str = "#version 200";
    const char* expected = "";

    using testing::_;
    // Directive successfully parsed.
    EXPECT_CALL(mDirectiveHandler,
                handleVersion(pp::SourceLocation(0, 1), 200));
    // Error reported about EOF.
    EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::EOF_IN_DIRECTIVE, _, _));

    preprocess(str, expected);
}

TEST_F(VersionTest, AfterComments)
{
    const char* str = "/* block comment acceptable */\n"
                      "// line comment acceptable\n"
                      "#version 200\n";
    const char* expected = "\n\n\n";

    using testing::_;
    // Directive successfully parsed.
    EXPECT_CALL(mDirectiveHandler,
                handleVersion(pp::SourceLocation(0, 3), 200));
    // No error or warning.
    EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
    
    preprocess(str, expected);
}

TEST_F(VersionTest, AfterWhitespace)
{
    const char* str = "\n"
                      "\n"
                      "#version 200\n";
    const char* expected = "\n\n\n";

    using testing::_;
    // Directive successfully parsed.
    EXPECT_CALL(mDirectiveHandler,
                handleVersion(pp::SourceLocation(0, 3), 200));
    // No error or warning.
    EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
    
    preprocess(str, expected);
}

TEST_F(VersionTest, AfterValidToken)
{
    const char* str = "foo\n"
                      "#version 200\n";
    ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));

    using testing::_;
    EXPECT_CALL(mDiagnostics,
                print(pp::Diagnostics::VERSION_NOT_FIRST_STATEMENT,
                      pp::SourceLocation(0, 2), _));

    pp::Token token;
    do
    {
        mPreprocessor.lex(&token);
    } while (token.type != pp::Token::LAST);
}

TEST_F(VersionTest, AfterInvalidToken)
{
    const char* str = "$\n"
                      "#version 200\n";
    ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));

    using testing::_;
    EXPECT_CALL(mDiagnostics,
                print(pp::Diagnostics::INVALID_CHARACTER,
                      pp::SourceLocation(0, 1), "$"));
    EXPECT_CALL(mDiagnostics,
                print(pp::Diagnostics::VERSION_NOT_FIRST_STATEMENT,
                      pp::SourceLocation(0, 2), _));

    pp::Token token;
    do
    {
        mPreprocessor.lex(&token);
    } while (token.type != pp::Token::LAST);
}

TEST_F(VersionTest, AfterValidDirective)
{
    const char* str = "#\n"
                      "#version 200\n";
    ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));

    using testing::_;
    EXPECT_CALL(mDiagnostics,
                print(pp::Diagnostics::VERSION_NOT_FIRST_STATEMENT,
                      pp::SourceLocation(0, 2), _));

    pp::Token token;
    do
    {
        mPreprocessor.lex(&token);
    } while (token.type != pp::Token::LAST);
}

TEST_F(VersionTest, AfterInvalidDirective)
{
    const char* str = "#foo\n"
                      "#version 200\n";
    ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));

    using testing::_;
    EXPECT_CALL(mDiagnostics,
                print(pp::Diagnostics::DIRECTIVE_INVALID_NAME,
                      pp::SourceLocation(0, 1), "foo"));
    EXPECT_CALL(mDiagnostics,
                print(pp::Diagnostics::VERSION_NOT_FIRST_STATEMENT,
                      pp::SourceLocation(0, 2), _));

    pp::Token token;
    do
    {
        mPreprocessor.lex(&token);
    } while (token.type != pp::Token::LAST);
}

TEST_F(VersionTest, AfterExcludedBlock)
{
    const char* str = "#if 0\n"
                      "foo\n"
                      "#endif\n"
                      "#version 200\n";
    ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));

    using testing::_;
    EXPECT_CALL(mDiagnostics,
                print(pp::Diagnostics::VERSION_NOT_FIRST_STATEMENT,
                      pp::SourceLocation(0, 4), _));

    pp::Token token;
    do
    {
        mPreprocessor.lex(&token);
    } while (token.type != pp::Token::LAST);
}

struct VersionTestParam
{
    const char* str;
    pp::Diagnostics::ID id;
};

class InvalidVersionTest : public VersionTest,
                           public testing::WithParamInterface<VersionTestParam>
{
};

TEST_P(InvalidVersionTest, Identified)
{
    VersionTestParam param = GetParam();
    const char* expected = "\n";

    using testing::_;
    // No handleVersion call.
    EXPECT_CALL(mDirectiveHandler, handleVersion(_, _)).Times(0);
    // Invalid version directive call.
    EXPECT_CALL(mDiagnostics, print(param.id, pp::SourceLocation(0, 1), _));

    preprocess(param.str, expected);
}

static const VersionTestParam kParams[] = {
    {"#version\n", pp::Diagnostics::INVALID_VERSION_DIRECTIVE},
    {"#version foo\n", pp::Diagnostics::INVALID_VERSION_NUMBER},
    {"#version 100 foo\n", pp::Diagnostics::UNEXPECTED_TOKEN},
    {"#version 0xffffffff\n", pp::Diagnostics::INTEGER_OVERFLOW}
};

INSTANTIATE_TEST_CASE_P(All, InvalidVersionTest, testing::ValuesIn(kParams));
