// 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 <iostream>
#include <string>
#include <unordered_set>

#include "src/tint/lang/wgsl/helpers/apply_substitute_overrides.h"
#include "src/tint/lang/wgsl/reader/lower/lower.h"
#include "src/tint/lang/wgsl/reader/parser/parser.h"
#include "src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.h"
#include "src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.h"
#include "src/tint/lang/wgsl/writer/raise/raise.h"
#include "src/tint/lang/wgsl/writer/writer.h"

[[noreturn]] void TintInternalCompilerErrorReporter(const tint::InternalCompilerError& err) {
    std::cerr << err.Error() << std::endl;
    __builtin_trap();
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    std::string str(reinterpret_cast<const char*>(data), size);

    tint::SetInternalCompilerErrorReporter(&TintInternalCompilerErrorReporter);

    tint::Source::File file("test.wgsl", str);

    // Parse the wgsl, create the src program
    tint::wgsl::reader::Parser parser(&file);
    parser.set_max_errors(1);
    if (!parser.Parse()) {
        return 0;
    }
    auto src = parser.program();
    if (!src.IsValid()) {
        return 0;
    }

    auto is_unsupported = [](const tint::ast::Enable* enable) {
        for (auto ext : enable->extensions) {
            switch (ext->name) {
                case tint::wgsl::Extension::kChromiumExperimentalDp4A:
                case tint::wgsl::Extension::kChromiumExperimentalFullPtrParameters:
                case tint::wgsl::Extension::kChromiumExperimentalPixelLocal:
                case tint::wgsl::Extension::kChromiumExperimentalPushConstant:
                case tint::wgsl::Extension::kChromiumInternalDualSourceBlending:
                case tint::wgsl::Extension::kChromiumInternalRelaxedUniformLayout:
                    return true;
                default:
                    break;
            }
        }
        return false;
    };

    if (src.AST().Enables().Any(is_unsupported)) {
        return 0;
    }

    if (auto transformed = tint::wgsl::ApplySubstituteOverrides(src)) {
        src = std::move(*transformed);
        if (!src.IsValid()) {
            return 0;
        }
    }

    auto ir = tint::wgsl::reader::ProgramToIR(src);
    if (!ir) {
        std::cerr << ir.Failure() << std::endl;
        __builtin_trap();
    }

    if (auto res = tint::wgsl::reader::Lower(ir.Get()); !res) {
        std::cerr << res.Failure() << std::endl;
        __builtin_trap();
    }

    if (auto res = tint::wgsl::writer::Raise(ir.Get()); !res) {
        std::cerr << res.Failure() << std::endl;
        __builtin_trap();
    }

    auto dst = tint::wgsl::writer::IRToProgram(ir.Get());
    if (!dst.IsValid()) {
#if TINT_BUILD_WGSL_WRITER
        if (auto result = tint::wgsl::writer::Generate(dst, {}); result) {
            std::cerr << result->wgsl << std::endl << std::endl;
        }
#endif

        std::cerr << dst.Diagnostics() << std::endl;
        __builtin_trap();
    }

    return 0;
}
