/*
 * 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);

  // VLQ with too many continuation digits. 7 continuation characters ('g')
  // push the shift to 35, exceeding the uint32_t width. This is a malformed
  // VLQ that should be rejected rather than causing undefined behavior.
  sourceMap = R"(
    {
      "version": 3,
      "sources": ["foo.c"],
      "mappings": "gggggggA"
    }
  )";
  ExpectParseError(sourceMap, "VLQ value too large");
}

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);
}
