// Copyright 2020 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.

#ifndef SRC_TINT_LANG_SPIRV_READER_AST_PARSER_HELPER_TEST_H_
#define SRC_TINT_LANG_SPIRV_READER_AST_PARSER_HELPER_TEST_H_

#include <memory>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

#include "src/tint/utils/macros/compiler.h"

TINT_BEGIN_DISABLE_WARNING(NEWLINE_EOF);
TINT_BEGIN_DISABLE_WARNING(OLD_STYLE_CAST);
TINT_BEGIN_DISABLE_WARNING(SIGN_CONVERSION);
TINT_BEGIN_DISABLE_WARNING(WEAK_VTABLES);
#include "source/opt/ir_context.h"
TINT_END_DISABLE_WARNING(WEAK_VTABLES);
TINT_END_DISABLE_WARNING(SIGN_CONVERSION);
TINT_END_DISABLE_WARNING(OLD_STYLE_CAST);
TINT_END_DISABLE_WARNING(NEWLINE_EOF);

#include "gtest/gtest.h"
#include "src/tint/lang/spirv/reader/ast_parser/ast_parser.h"
#include "src/tint/lang/spirv/reader/ast_parser/fail_stream.h"
#include "src/tint/lang/spirv/reader/ast_parser/function.h"
#include "src/tint/lang/spirv/reader/ast_parser/namer.h"
#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
#include "src/tint/lang/spirv/reader/ast_parser/usage.h"

namespace tint::spirv::reader::ast_parser::test {

/// A test class that wraps ParseImpl
class ASTParserWrapperForTest {
  public:
    /// Constructor
    /// @param input the input data to parse
    explicit ASTParserWrapperForTest(const std::vector<uint32_t>& input);
    /// Dumps SPIR-V if the conversion succeeded, then destroys the wrapper.
    ~ASTParserWrapperForTest();

    /// Sets global state to force dumping of the assembly text of succesfully
    /// SPIR-V.
    static void DumpSuccessfullyConvertedSpirv() { dump_successfully_converted_spirv_ = true; }
    /// Marks the test has having deliberately invalid SPIR-V
    void DeliberatelyInvalidSpirv() { skip_dumping_spirv_ = true; }
    /// Marks the test's SPIR-V as not being suitable for dumping, for a stated
    /// reason.
    void SkipDumpingPending(std::string) { skip_dumping_spirv_ = true; }

    /// @returns a new function emitter for the given function ID.
    /// Assumes ASTParser::BuildInternalRepresentation has been run and
    /// succeeded.
    /// @param function_id the SPIR-V identifier of the function
    FunctionEmitter function_emitter(uint32_t function_id) {
        auto* spirv_function = impl_.ir_context()->GetFunction(function_id);
        return FunctionEmitter(&impl_, *spirv_function);
    }

    /// Run the parser
    /// @returns true if the parse was successful, false otherwise.
    bool Parse() { return impl_.Parse(); }

    /// @returns the program. The program builder in the parser will be reset
    /// after this.
    Program program() { return impl_.Program(resolve_); }

    /// @returns the namer object
    Namer& namer() { return impl_.namer(); }

    /// @returns a reference to the internal builder, without building the
    /// program. To be used only for testing.
    ProgramBuilder& builder() { return impl_.builder(); }

    /// @returns the accumulated error string
    const std::string error() { return impl_.error(); }

    /// @return true if failure has not yet occurred
    bool success() { return impl_.success(); }

    /// Logs failure, ands return a failure stream to accumulate diagnostic
    /// messages. By convention, a failure should only be logged along with
    /// a non-empty string diagnostic.
    /// @returns the failure stream
    FailStream& Fail() { return impl_.Fail(); }

    /// @returns a borrowed pointer to the internal representation of the module.
    /// This is null until BuildInternalModule has been called.
    spvtools::opt::IRContext* ir_context() { return impl_.ir_context(); }

    /// Builds the internal representation of the SPIR-V module.
    /// Assumes the module is somewhat well-formed.  Normally you
    /// would want to validate the SPIR-V module before attempting
    /// to build this internal representation. Also computes a topological
    /// ordering of the functions.
    /// This is a no-op if the parser has already failed.
    /// @returns true if the parser is still successful.
    bool BuildInternalModule() { return impl_.BuildInternalModule(); }

    /// Builds an internal representation of the SPIR-V binary,
    /// and parses the module, except functions, into a Tint AST module.
    /// Diagnostics are emitted to the error stream.
    /// @returns true if it was successful.
    bool BuildAndParseInternalModuleExceptFunctions() {
        return impl_.BuildAndParseInternalModuleExceptFunctions();
    }

    /// Builds an internal representation of the SPIR-V binary,
    /// and parses it into a Tint AST module.  Diagnostics are emitted
    /// to the error stream.
    /// @returns true if it was successful.
    bool BuildAndParseInternalModule() { return impl_.BuildAndParseInternalModule(); }

    /// Registers user names for SPIR-V objects, from OpName, and OpMemberName.
    /// Also synthesizes struct field names.  Ensures uniqueness for names for
    /// SPIR-V IDs, and uniqueness of names of fields within any single struct.
    /// This is a no-op if the parser has already failed.
    /// @returns true if parser is still successful.
    bool RegisterUserAndStructMemberNames() { return impl_.RegisterUserAndStructMemberNames(); }

    /// Register Tint AST types for SPIR-V types, including type aliases as
    /// needed.  This is a no-op if the parser has already failed.
    /// @returns true if parser is still successful.
    bool RegisterTypes() { return impl_.RegisterTypes(); }

    /// Register sampler and texture usage for memory object declarations.
    /// This must be called after we've registered line numbers for all
    /// instructions. This is a no-op if the parser has already failed.
    /// @returns true if parser is still successful.
    bool RegisterHandleUsage() { return impl_.RegisterHandleUsage(); }

    /// Emits module-scope variables.
    /// This is a no-op if the parser has already failed.
    /// @returns true if parser is still successful.
    bool EmitModuleScopeVariables() { return impl_.EmitModuleScopeVariables(); }

    /// @returns the set of SPIR-V IDs for imports of the "GLSL.std.450"
    /// extended instruction set.
    const std::unordered_set<uint32_t>& glsl_std_450_imports() const {
        return impl_.glsl_std_450_imports();
    }

    /// Converts a SPIR-V type to a Tint type, and saves it for fast lookup.
    /// If the type is only used for builtins, then register that specially,
    /// and return null.  If the type is a sampler, image, or sampled image, then
    /// return the Void type, because those opaque types are handled in a
    /// different way.
    /// On failure, logs an error and returns null.  This should only be called
    /// after the internal representation of the module has been built.
    /// @param id the SPIR-V ID of a type.
    /// @returns a Tint type, or nullptr
    const Type* ConvertType(uint32_t id) { return impl_.ConvertType(id); }

    /// Gets the list of decorations for a SPIR-V result ID.  Returns an empty
    /// vector if the ID is not a result ID, or if no decorations target that ID.
    /// The internal representation must have already been built.
    /// @param id SPIR-V ID
    /// @returns the list of decorations on the given ID
    DecorationList GetDecorationsFor(uint32_t id) const { return impl_.GetDecorationsFor(id); }

    /// Gets the list of decorations for the member of a struct.  Returns an empty
    /// list if the `id` is not the ID of a struct, or if the member index is out
    /// of range, or if the target member has no decorations.
    /// The internal representation must have already been built.
    /// @param id SPIR-V ID of a struct
    /// @param member_index the member within the struct
    /// @returns the list of decorations on the member
    DecorationList GetDecorationsForMember(uint32_t id, uint32_t member_index) const {
        return impl_.GetDecorationsForMember(id, member_index);
    }

    /// Converts a SPIR-V struct member decoration into a number of AST
    /// decorations. If the decoration is recognized but deliberately dropped,
    /// then returns an empty list without a diagnostic. On failure, emits a
    /// diagnostic and returns an empty list.
    /// @param struct_type_id the ID of the struct type
    /// @param member_index the index of the member
    /// @param member_ty the type of the member
    /// @param decoration an encoded SPIR-V Decoration
    /// @returns the AST decorations
    auto ConvertMemberDecoration(uint32_t struct_type_id,
                                 uint32_t member_index,
                                 const Type* member_ty,
                                 const Decoration& decoration) {
        return impl_.ConvertMemberDecoration(struct_type_id, member_index, member_ty, decoration);
    }

    /// For a SPIR-V ID that might define a sampler, image, or sampled image
    /// value, return the SPIR-V instruction that represents the memory object
    /// declaration for the object.  If we encounter an OpSampledImage along the
    /// way, follow the image operand when follow_image is true; otherwise follow
    /// the sampler operand. Returns nullptr if we can't trace back to a memory
    /// object declaration.  Emits an error and returns nullptr when the scan
    /// fails due to a malformed module. This method can be used any time after
    /// BuildInternalModule has been invoked.
    /// @param id the SPIR-V ID of the sampler, image, or sampled image
    /// @param follow_image indicates whether to follow the image operand of
    /// OpSampledImage
    /// @returns the memory object declaration for the handle, or nullptr
    const spvtools::opt::Instruction* GetMemoryObjectDeclarationForHandle(uint32_t id,
                                                                          bool follow_image) {
        return impl_.GetMemoryObjectDeclarationForHandle(id, follow_image);
    }

    /// @param entry_point the SPIR-V ID of an entry point.
    /// @returns the entry point info for the given ID
    const std::vector<EntryPointInfo>& GetEntryPointInfo(uint32_t entry_point) {
        return impl_.GetEntryPointInfo(entry_point);
    }

    /// Returns the handle usage for a memory object declaration.
    /// @param id SPIR-V ID of a sampler or image OpVariable or
    /// OpFunctionParameter
    /// @returns the handle usage, or an empty usage object.
    Usage GetHandleUsage(uint32_t id) const { return impl_.GetHandleUsage(id); }

    /// Returns the SPIR-V instruction with the given ID, or nullptr.
    /// @param id the SPIR-V result ID
    /// @returns the instruction, or nullptr on error
    const spvtools::opt::Instruction* GetInstructionForTest(uint32_t id) const {
        return impl_.GetInstructionForTest(id);
    }

    /// @returns info about the gl_Position builtin variable.
    const ASTParser::BuiltInPositionInfo& GetBuiltInPositionInfo() {
        return impl_.GetBuiltInPositionInfo();
    }

    /// Returns the source record for the SPIR-V instruction with the given
    /// result ID.
    /// @param id the SPIR-V result id.
    /// @return the Source record, or a default one
    Source GetSourceForResultIdForTest(uint32_t id) const {
        return impl_.GetSourceForResultIdForTest(id);
    }

    /// @param resolve if true, the resolver should be run on the program when its build
    void SetResolveOnBuild(bool resolve) { resolve_ = resolve; }

  private:
    ASTParser impl_;
    /// When true, indicates the input SPIR-V module should not be emitted.
    /// It's either deliberately invalid, or not supported for some pending
    /// reason.
    bool skip_dumping_spirv_ = false;
    static bool dump_successfully_converted_spirv_;
    bool resolve_ = true;
};

// Sets global state to force dumping of the assembly text of succesfully
// SPIR-V.
inline void DumpSuccessfullyConvertedSpirv() {
    ASTParserWrapperForTest::DumpSuccessfullyConvertedSpirv();
}

/// Returns the WGSL printed string of a program.
/// @param program the Program
/// @returns the WGSL printed string the program.
std::string ToString(const Program& program);

/// Returns the WGSL printed string of a statement list.
/// @param program the Program
/// @param stmts the statement list
/// @returns the WGSL printed string of a statement list.
std::string ToString(const Program& program, VectorRef<const ast::Statement*> stmts);

/// Returns the WGSL printed string of an AST node.
/// @param program the Program
/// @param node the AST node
/// @returns the WGSL printed string of the AST node.
std::string ToString(const Program& program, const ast::Node* node);

}  // namespace tint::spirv::reader::ast_parser::test

namespace tint::spirv::reader::ast_parser {

/// SPIR-V Parser test class
template <typename T>
class SpirvASTParserTestBase : public T {
  public:
    SpirvASTParserTestBase() = default;
    ~SpirvASTParserTestBase() override = default;

    /// Retrieves the parser from the helper
    /// @param input the SPIR-V binary to parse
    /// @returns a parser for the given binary
    std::unique_ptr<test::ASTParserWrapperForTest> parser(const std::vector<uint32_t>& input) {
        auto parser = std::make_unique<test::ASTParserWrapperForTest>(input);
        // Don't run the Resolver when building the program.
        // We're not interested in type information with these tests.
        parser->SetResolveOnBuild(false);
        return parser;
    }
};

/// SpirvASTParserTest the the base class for SPIR-V reader unit tests.
/// Use this form when you don't need to template any further.
using SpirvASTParserTest = SpirvASTParserTestBase<::testing::Test>;

}  // namespace tint::spirv::reader::ast_parser

#endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_HELPER_TEST_H_
