/*
 * Copyright 2024 WebAssembly Community Group participants
 *
 * 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 "source-map.h"
#include "ir/module-utils.h"
#include "print-test.h"
#include "wasm-builder.h"
#include "gmock/gmock-matchers.h"
#include "gtest/gtest.h"

using namespace wasm;

class SourceMapTest : public PrintTest {
  std::vector<char> buffer;

protected:
  Module wasm;
  std::unique_ptr<SourceMapReader> reader;

  void SetUp() override {
    PrintTest::SetUp();
    reader.reset();
    parseWast(wasm, "(module)");
  }

  void parseMap(std::string& sourceMap) {
    buffer = {sourceMap.begin(), sourceMap.end()};
    reader.reset(new SourceMapReader(buffer));
    reader->parse(wasm);
  }

  void ExpectDbgLocEq(size_t location,
                      BinaryLocation file,
                      BinaryLocation line,
                      BinaryLocation col,
                      std::optional<BinaryLocation> sym) {
    auto loc_str = std::stringstream() << "location: " << location;
    SCOPED_TRACE(loc_str.str());
    auto loc = reader->readDebugLocationAt(location);
    ASSERT_TRUE(loc.has_value());
    EXPECT_EQ(loc->fileIndex, file);
    EXPECT_EQ(loc->lineNumber, line);
    EXPECT_EQ(loc->columnNumber, col);
    EXPECT_EQ(loc->symbolNameIndex, sym);
  }

  void ExpectParseError(std::string& mapString, const char* expectedError) {
    SCOPED_TRACE(mapString);
    EXPECT_THROW(parseMap(mapString), MapParseException);
    try {
      parseMap(mapString);
    } catch (MapParseException ex) {
      EXPECT_THAT(ex.errorText, ::testing::HasSubstr(expectedError));
    }
  }
};

// Check that debug location parsers can handle single-segment mappings.
TEST_F(SourceMapTest, SourceMappingSingleSegment) {
  // A single-segment mapping starting at offset 0.
  std::string sourceMap = R"(
      {
          "version": 3,
          "sources": [],
          "sourcesContent": [],
          "names": [],
          "mappings": "A"
      }
  )";
  parseMap(sourceMap);

  auto loc = reader->readDebugLocationAt(0);
  EXPECT_FALSE(loc.has_value());
}

TEST_F(SourceMapTest, BadSourceMaps) {
  // Test that a malformed JSON string throws rather than asserting.
  std::string sourceMap = R"(
    {
      "version": 3,
      "sources": ["foo.c"],
      "mappings": ""
    malformed
    }
  )";
  ExpectParseError(sourceMap, "malformed value in JSON object");

  // Valid JSON, but missing the version field.
  sourceMap = R"(
    {
      "sources": [],
      "names": [],
      "mappings": "A"
    }
  )";
  ExpectParseError(sourceMap, "Source map version missing");

  // Valid JSON, but a bad "sources" field.
  sourceMap = R"(
    {
      "version": 3,
      "sources": 123,
      "mappings": ""
    }
  )";
  ExpectParseError(sourceMap, "Source map sources missing or not an array");

  sourceMap = R"(
    {
      "version": 3,
      "sources": ["foo.c"],
      "mappings": "C;A"
    }
  )";
  parseMap(sourceMap);
  // Mapping strings are parsed incrementally, so errors don't show up until a
  // sufficiently far-advanced location is requested to reach the problem.
  EXPECT_THROW(reader->readDebugLocationAt(1), MapParseException);
}

TEST_F(SourceMapTest, SourcesAndNames) {
  std::string sourceMap = R"(
    {
      "version": 3,
      "sources": ["foo.c", "bar.c"],
      "names": ["foo", "bar"],
      "mappings": ""
    }
  )";
  parseMap(sourceMap);

  EXPECT_EQ(wasm.debugInfoFileNames.size(), 2);
  EXPECT_EQ(wasm.debugInfoFileNames[0], "foo.c");
  EXPECT_EQ(wasm.debugInfoFileNames[1], "bar.c");
  EXPECT_EQ(wasm.debugInfoSymbolNames.size(), 2);
  EXPECT_EQ(wasm.debugInfoSymbolNames[0], "foo");
  EXPECT_EQ(wasm.debugInfoSymbolNames[1], "bar");
}

TEST_F(SourceMapTest, OptionalFields) {
  // The "names" field is optional.
  std::string sourceMap = R"(
    {
      "version": 3,
      "sources": [],
      "mappings": "A"
    }
  )";
  parseMap(sourceMap);
}

// This map is taken from test/fib-dbg.wasm
TEST_F(SourceMapTest, Fibonacci) {
  // Test mapping parsing and debug locs
  std::string sourceMap = R"(
    {
      "version":3,
      "sources":["fib.c"],
      "names":[],
      "mappings": "moBAEA,4BAKA,QAJA,OADA,OAAA,uCAKA"
    }
  )";
  parseMap(sourceMap);

  // Location before the first record has no value
  auto loc = reader->readDebugLocationAt(642);
  EXPECT_FALSE(loc.has_value());

  // TODO: These column numbers show as 0 but emsymbolizer.py prints them as 1.
  // Figure out which is right.
  // First location
  ExpectDbgLocEq(643, 0, 3, 0, std::nullopt);
  // locations in between records have the same value as the previous one.
  for (size_t l = 644; l < 671; l++) {
    ExpectDbgLocEq(l, 0, 3, 0, std::nullopt);
  }
  // Subsequent ones are on record boundaries
  ExpectDbgLocEq(671, 0, 8, 0, std::nullopt);
  ExpectDbgLocEq(679, 0, 4, 0, std::nullopt);
  ExpectDbgLocEq(686, 0, 3, 0, std::nullopt);
  ExpectDbgLocEq(693, 0, 3, 0, std::nullopt);
  ExpectDbgLocEq(732, 0, 8, 0, std::nullopt);
  // Entries after the last record have the same value as the last one.
  ExpectDbgLocEq(733, 0, 8, 0, std::nullopt);
  // Should we return empty values for locations that are past the end of the
  // program?
  ExpectDbgLocEq(9999, 0, 8, 0, std::nullopt);
}

TEST_F(SourceMapTest, SourceMapSourceRootFile) {
  std::string sourceMap = R"(
    {
      "version":3,
      "file": "foo.wasm",
      "sources":[],
      "names":[],
      "mappings": "",
      "sourceRoot": "/foo/bar"
    }
  )";
  parseMap(sourceMap);
  EXPECT_EQ(wasm.debugInfoSourceRoot, "/foo/bar");
  EXPECT_EQ(wasm.debugInfoFile, "foo.wasm");
}

TEST_F(SourceMapTest, SourcesContent) {
  // The backslash escapes appear in the JSON encoding, and are preserved in
  // the internal representation. The string values are uninterpreted in
  // Binaryen, and they are written directly back out without re-encoding.
  std::string sourceMap = R"(
   {
     "version": 3,
     "sources": ["foo.c"],
     "sourcesContent": ["#include <stdio.h> int main()\n{ printf(\"Gr\u00fc\u00df Gott, Welt!\"); return 0;}"],
     "mappings" : ""
   }
  )";
  parseMap(sourceMap);
  ASSERT_EQ(wasm.debugInfoSourcesContent.size(), 1);
  EXPECT_EQ(wasm.debugInfoSourcesContent[0],
            "#include <stdio.h> int main()\\n{ printf(\\\"Gr\\u00fc\\u00df "
            "Gott, Welt!\\\"); return 0;}");
}

// Regression test: updateSymbol calls for prologLocation/epilogLocation were
// inside the debugLocations loop instead of outside. When debugLocations is
// empty, the loop never executes and the locations are not updated.
TEST(SourceMapCopyTest, UpdateSymbolOutsideLoop) {
  Module srcModule;
  Module dstModule;
  Builder builder(srcModule);

  auto func = builder.makeFunction(
    "test", {}, Signature(Type::none, Type::none), {}, builder.makeNop());

  // Set prologLocation and epilogLocation with symbolNameIndex values,
  // but leave debugLocations empty.
  func->prologLocation =
    Function::DebugLocation{0, 1, 1, std::optional<BinaryLocation>(0)};
  func->epilogLocation =
    Function::DebugLocation{0, 2, 1, std::optional<BinaryLocation>(1)};

  // Symbol name index map: 0->10, 1->11.
  std::vector<Index> symbolNameIndexMap = {10, 11};

  auto copied = ModuleUtils::copyFunctionWithoutAdd(
    func.get(), dstModule, Name(), std::nullopt, symbolNameIndexMap);

  ASSERT_TRUE(copied->prologLocation.has_value());
  ASSERT_TRUE(copied->prologLocation->symbolNameIndex.has_value());
  EXPECT_EQ(*copied->prologLocation->symbolNameIndex, 10u);

  ASSERT_TRUE(copied->epilogLocation.has_value());
  ASSERT_TRUE(copied->epilogLocation->symbolNameIndex.has_value());
  EXPECT_EQ(*copied->epilogLocation->symbolNameIndex, 11u);
}

// When debugLocations has multiple entries, updateSymbol should only run once
// per location, not once per loop iteration (which would double-remap).
TEST(SourceMapCopyTest, UpdateSymbolNotDoubleRemapped) {
  Module srcModule;
  Module dstModule;
  Builder builder(srcModule);

  auto func = builder.makeFunction(
    "test", {}, Signature(Type::none, Type::none), {}, builder.makeNop());

  func->prologLocation =
    Function::DebugLocation{0, 1, 1, std::optional<BinaryLocation>(0)};

  // Add multiple debug locations so the loop runs multiple times.
  auto* nop1 = srcModule.allocator.alloc<Nop>();
  auto* nop2 = srcModule.allocator.alloc<Nop>();
  func->debugLocations[nop1] =
    Function::DebugLocation{0, 10, 1, std::optional<BinaryLocation>(0)};
  func->debugLocations[nop2] =
    Function::DebugLocation{0, 11, 1, std::optional<BinaryLocation>(1)};

  // Map: 0->5, 1->6.
  std::vector<Index> symbolNameIndexMap = {5, 6};

  auto copied = ModuleUtils::copyFunctionWithoutAdd(
    func.get(), dstModule, Name(), std::nullopt, symbolNameIndexMap);

  // Should be remapped exactly once: 0 -> 5.
  ASSERT_TRUE(copied->prologLocation.has_value());
  ASSERT_TRUE(copied->prologLocation->symbolNameIndex.has_value());
  EXPECT_EQ(*copied->prologLocation->symbolNameIndex, 5u);
}
