// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/inspector/v8-debugger-script.h"

#include "src/inspector/inspected-context.h"
#include "src/inspector/string-util.h"
#include "src/inspector/wasm-translation.h"

namespace v8_inspector {

namespace {

const char hexDigits[17] = "0123456789ABCDEF";

void appendUnsignedAsHex(uint64_t number, String16Builder* destination) {
  for (size_t i = 0; i < 8; ++i) {
    UChar c = hexDigits[number & 0xF];
    destination->append(c);
    number >>= 4;
  }
}

// Hash algorithm for substrings is described in "Über die Komplexität der
// Multiplikation in
// eingeschränkten Branchingprogrammmodellen" by Woelfe.
// http://opendatastructures.org/versions/edition-0.1d/ods-java/node33.html#SECTION00832000000000000000
String16 calculateHash(const String16& str) {
  static uint64_t prime[] = {0x3FB75161, 0xAB1F4E4F, 0x82675BC5, 0xCD924D35,
                             0x81ABE279};
  static uint64_t random[] = {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476,
                              0xC3D2E1F0};
  static uint32_t randomOdd[] = {0xB4663807, 0xCC322BF5, 0xD4F91BBD, 0xA7BEA11D,
                                 0x8F462907};

  uint64_t hashes[] = {0, 0, 0, 0, 0};
  uint64_t zi[] = {1, 1, 1, 1, 1};

  const size_t hashesSize = arraysize(hashes);

  size_t current = 0;
  const uint32_t* data = nullptr;
  size_t sizeInBytes = sizeof(UChar) * str.length();
  data = reinterpret_cast<const uint32_t*>(str.characters16());
  for (size_t i = 0; i < sizeInBytes / 4; i += 4) {
    uint32_t v = data[i];
    uint64_t xi = v * randomOdd[current] & 0x7FFFFFFF;
    hashes[current] = (hashes[current] + zi[current] * xi) % prime[current];
    zi[current] = (zi[current] * random[current]) % prime[current];
    current = current == hashesSize - 1 ? 0 : current + 1;
  }
  if (sizeInBytes % 4) {
    uint32_t v = 0;
    for (size_t i = sizeInBytes - sizeInBytes % 4; i < sizeInBytes; ++i) {
      v <<= 8;
      v |= reinterpret_cast<const uint8_t*>(data)[i];
    }
    uint64_t xi = v * randomOdd[current] & 0x7FFFFFFF;
    hashes[current] = (hashes[current] + zi[current] * xi) % prime[current];
    zi[current] = (zi[current] * random[current]) % prime[current];
    current = current == hashesSize - 1 ? 0 : current + 1;
  }

  for (size_t i = 0; i < hashesSize; ++i)
    hashes[i] = (hashes[i] + zi[i] * (prime[i] - 1)) % prime[i];

  String16Builder hash;
  for (size_t i = 0; i < hashesSize; ++i) appendUnsignedAsHex(hashes[i], &hash);
  return hash.toString();
}

void TranslateProtocolLocationToV8Location(WasmTranslation* wasmTranslation,
                                           v8::debug::Location* loc,
                                           const String16& scriptId,
                                           const String16& expectedV8ScriptId) {
  if (loc->IsEmpty()) return;
  int lineNumber = loc->GetLineNumber();
  int columnNumber = loc->GetColumnNumber();
  String16 translatedScriptId = scriptId;
  wasmTranslation->TranslateProtocolLocationToWasmScriptLocation(
      &translatedScriptId, &lineNumber, &columnNumber);
  DCHECK_EQ(expectedV8ScriptId.utf8(), translatedScriptId.utf8());
  *loc = v8::debug::Location(lineNumber, columnNumber);
}

void TranslateV8LocationToProtocolLocation(
    WasmTranslation* wasmTranslation, v8::debug::Location* loc,
    const String16& scriptId, const String16& expectedProtocolScriptId) {
  int lineNumber = loc->GetLineNumber();
  int columnNumber = loc->GetColumnNumber();
  String16 translatedScriptId = scriptId;
  wasmTranslation->TranslateWasmScriptLocationToProtocolLocation(
      &translatedScriptId, &lineNumber, &columnNumber);
  DCHECK_EQ(expectedProtocolScriptId.utf8(), translatedScriptId.utf8());
  *loc = v8::debug::Location(lineNumber, columnNumber);
}

class ActualScript : public V8DebuggerScript {
  friend class V8DebuggerScript;

 public:
  ActualScript(v8::Isolate* isolate, v8::Local<v8::debug::Script> script,
               bool isLiveEdit)
      : V8DebuggerScript(isolate, String16::fromInteger(script->Id()),
                         GetNameOrSourceUrl(script)),
        m_isLiveEdit(isLiveEdit) {
    v8::Local<v8::String> tmp;
    if (script->SourceURL().ToLocal(&tmp)) m_sourceURL = toProtocolString(tmp);
    if (script->SourceMappingURL().ToLocal(&tmp))
      m_sourceMappingURL = toProtocolString(tmp);
    m_startLine = script->LineOffset();
    m_startColumn = script->ColumnOffset();
    std::vector<int> lineEnds = script->LineEnds();
    CHECK(lineEnds.size());
    int source_length = lineEnds[lineEnds.size() - 1];
    if (lineEnds.size()) {
      m_endLine = static_cast<int>(lineEnds.size()) + m_startLine - 1;
      if (lineEnds.size() > 1) {
        m_endColumn = source_length - lineEnds[lineEnds.size() - 2] - 1;
      } else {
        m_endColumn = source_length + m_startColumn;
      }
    } else {
      m_endLine = m_startLine;
      m_endColumn = m_startColumn;
    }

    v8::Local<v8::Value> contextData;
    if (script->ContextData().ToLocal(&contextData) && contextData->IsInt32()) {
      m_executionContextId =
          static_cast<int>(contextData.As<v8::Int32>()->Value());
    }

    if (script->Source().ToLocal(&tmp)) {
      m_sourceObj.Reset(m_isolate, tmp);
      String16 source = toProtocolString(tmp);
      // V8 will not count last line if script source ends with \n.
      if (source.length() > 1 && source[source.length() - 1] == '\n') {
        m_endLine++;
        m_endColumn = 0;
      }
    }

    m_isModule = script->IsModule();

    m_script.Reset(m_isolate, script);
  }

  bool isLiveEdit() const override { return m_isLiveEdit; }
  bool isModule() const override { return m_isModule; }

  const String16& sourceMappingURL() const override {
    return m_sourceMappingURL;
  }

  String16 source(v8::Isolate* isolate) const override {
    if (!m_sourceObj.IsEmpty())
      return toProtocolString(m_sourceObj.Get(isolate));
    return V8DebuggerScript::source(isolate);
  }

  void setSourceMappingURL(const String16& sourceMappingURL) override {
    m_sourceMappingURL = sourceMappingURL;
  }

  void setSource(v8::Local<v8::String> source) override {
    m_source = String16();
    m_sourceObj.Reset(m_isolate, source);
    m_hash = String16();
  }

  bool getPossibleBreakpoints(
      const v8::debug::Location& start, const v8::debug::Location& end,
      std::vector<v8::debug::Location>* locations) override {
    v8::HandleScope scope(m_isolate);
    v8::Local<v8::debug::Script> script = m_script.Get(m_isolate);
    return script->GetPossibleBreakpoints(start, end, locations);
  }

  void resetBlackboxedStateCache() override {
    v8::HandleScope scope(m_isolate);
    v8::debug::ResetBlackboxedStateCache(m_isolate, m_script.Get(m_isolate));
  }

 private:
  String16 GetNameOrSourceUrl(v8::Local<v8::debug::Script> script) {
    v8::Local<v8::String> name;
    if (script->Name().ToLocal(&name) || script->SourceURL().ToLocal(&name))
      return toProtocolString(name);
    return String16();
  }

  String16 m_sourceMappingURL;
  v8::Global<v8::String> m_sourceObj;
  bool m_isLiveEdit = false;
  bool m_isModule = false;
  v8::Global<v8::debug::Script> m_script;
};

class WasmVirtualScript : public V8DebuggerScript {
  friend class V8DebuggerScript;

 public:
  WasmVirtualScript(v8::Isolate* isolate, WasmTranslation* wasmTranslation,
                    v8::Local<v8::debug::WasmScript> script, String16 id,
                    String16 url, String16 source)
      : V8DebuggerScript(isolate, std::move(id), std::move(url)),
        m_script(isolate, script),
        m_wasmTranslation(wasmTranslation) {
    int num_lines = 0;
    int last_newline = -1;
    size_t next_newline = source.find('\n', last_newline + 1);
    while (next_newline != String16::kNotFound) {
      last_newline = static_cast<int>(next_newline);
      next_newline = source.find('\n', last_newline + 1);
      ++num_lines;
    }
    m_endLine = num_lines;
    m_endColumn = static_cast<int>(source.length()) - last_newline - 1;
    m_source = std::move(source);
  }

  const String16& sourceMappingURL() const override { return emptyString(); }
  bool isLiveEdit() const override { return false; }
  bool isModule() const override { return false; }
  void setSourceMappingURL(const String16&) override {}

  bool getPossibleBreakpoints(
      const v8::debug::Location& start, const v8::debug::Location& end,
      std::vector<v8::debug::Location>* locations) override {
    v8::HandleScope scope(m_isolate);
    v8::Local<v8::debug::Script> script = m_script.Get(m_isolate);
    String16 v8ScriptId = String16::fromInteger(script->Id());

    v8::debug::Location translatedStart = start;
    TranslateProtocolLocationToV8Location(m_wasmTranslation, &translatedStart,
                                          scriptId(), v8ScriptId);

    v8::debug::Location translatedEnd = end;
    if (translatedEnd.IsEmpty()) {
      // Stop before the start of the next function.
      translatedEnd =
          v8::debug::Location(translatedStart.GetLineNumber() + 1, 0);
    } else {
      TranslateProtocolLocationToV8Location(m_wasmTranslation, &translatedEnd,
                                            scriptId(), v8ScriptId);
    }

    bool success = script->GetPossibleBreakpoints(translatedStart,
                                                  translatedEnd, locations);
    for (v8::debug::Location& loc : *locations) {
      TranslateV8LocationToProtocolLocation(m_wasmTranslation, &loc, v8ScriptId,
                                            scriptId());
    }
    return success;
  }

  void resetBlackboxedStateCache() override {}

 private:
  static const String16& emptyString() {
    static const String16 singleEmptyString;
    return singleEmptyString;
  }

  v8::Global<v8::debug::WasmScript> m_script;
  WasmTranslation* m_wasmTranslation;
};

}  // namespace

std::unique_ptr<V8DebuggerScript> V8DebuggerScript::Create(
    v8::Isolate* isolate, v8::Local<v8::debug::Script> scriptObj,
    bool isLiveEdit) {
  return std::unique_ptr<ActualScript>(
      new ActualScript(isolate, scriptObj, isLiveEdit));
}

std::unique_ptr<V8DebuggerScript> V8DebuggerScript::CreateWasm(
    v8::Isolate* isolate, WasmTranslation* wasmTranslation,
    v8::Local<v8::debug::WasmScript> underlyingScript, String16 id,
    String16 url, String16 source) {
  return std::unique_ptr<WasmVirtualScript>(
      new WasmVirtualScript(isolate, wasmTranslation, underlyingScript,
                            std::move(id), std::move(url), std::move(source)));
}

V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, String16 id,
                                   String16 url)
    : m_id(std::move(id)), m_url(std::move(url)), m_isolate(isolate) {}

V8DebuggerScript::~V8DebuggerScript() {}

const String16& V8DebuggerScript::sourceURL() const {
  return m_sourceURL.isEmpty() ? m_url : m_sourceURL;
}

const String16& V8DebuggerScript::hash(v8::Isolate* isolate) const {
  if (m_hash.isEmpty()) m_hash = calculateHash(source(isolate));
  DCHECK(!m_hash.isEmpty());
  return m_hash;
}

void V8DebuggerScript::setSourceURL(const String16& sourceURL) {
  m_sourceURL = sourceURL;
}

}  // namespace v8_inspector
