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

#include <iostream>
#include <string>
#include <unordered_set>

#include "src/tint/reader/wgsl/parser_impl.h"
#include "src/tint/writer/wgsl/generator.h"

#define ASSERT_EQ(A, B)                                  \
  do {                                                   \
    decltype(A) assert_a = (A);                          \
    decltype(B) assert_b = (B);                          \
    if (assert_a != assert_b) {                          \
      std::cerr << "ASSERT_EQ(" #A ", " #B ") failed:\n" \
                << #A << " was: " << assert_a << "\n"    \
                << #B << " was: " << assert_b << "\n";   \
      __builtin_trap();                                  \
    }                                                    \
  } while (false)

#define ASSERT_TRUE(A)                                 \
  do {                                                 \
    decltype(A) assert_a = (A);                        \
    if (!assert_a) {                                   \
      std::cerr << "ASSERT_TRUE(" #A ") failed:\n"     \
                << #A << " was: " << assert_a << "\n"; \
      __builtin_trap();                                \
    }                                                  \
  } while (false)

[[noreturn]] void TintInternalCompilerErrorReporter(
    const tint::diag::List& diagnostics) {
  auto printer = tint::diag::Printer::create(stderr, true);
  tint::diag::Formatter{}.format(diagnostics, printer.get());
  __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::reader::wgsl::ParserImpl parser(&file);
  parser.set_max_errors(1);
  if (!parser.Parse()) {
    return 0;
  }
  auto src = parser.program();
  if (!src.IsValid()) {
    return 0;
  }

  // Clone the src program to dst
  tint::Program dst(src.Clone());

  // Expect the printed strings to match
  ASSERT_EQ(tint::Program::printer(&src), tint::Program::printer(&dst));

  // Check that none of the AST nodes or type pointers in dst are found in src
  std::unordered_set<const tint::ast::Node*> src_nodes;
  for (auto* src_node : src.ASTNodes().Objects()) {
    src_nodes.emplace(src_node);
  }
  std::unordered_set<const tint::sem::Type*> src_types;
  for (auto* src_type : src.Types()) {
    src_types.emplace(src_type);
  }
  for (auto* dst_node : dst.ASTNodes().Objects()) {
    ASSERT_EQ(src_nodes.count(dst_node), 0u);
  }
  for (auto* dst_type : dst.Types()) {
    ASSERT_EQ(src_types.count(dst_type), 0u);
  }

  // Regenerate the wgsl for the src program. We use this instead of the
  // original source so that reformatting doesn't impact the final wgsl
  // comparison.
  std::string src_wgsl;
  tint::writer::wgsl::Options wgsl_options;
  {
    auto result = tint::writer::wgsl::Generate(&src, wgsl_options);
    ASSERT_TRUE(result.success);
    src_wgsl = result.wgsl;

    // Move the src program to a temporary that'll be dropped, so that the src
    // program is released before we attempt to print the dst program. This
    // guarantee that all the source program nodes and types are destructed and
    // freed. ASAN should error if there's any remaining references in dst when
    // we try to reconstruct the WGSL.
    auto tmp = std::move(src);
  }

  // Print the dst program, check it matches the original source
  auto result = tint::writer::wgsl::Generate(&dst, wgsl_options);
  ASSERT_TRUE(result.success);
  auto dst_wgsl = result.wgsl;
  ASSERT_EQ(src_wgsl, dst_wgsl);

  return 0;
}
