// Copyright 2022 The Cobalt Authors. All Rights Reserved.
//
// 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 "cobalt/web/cache_utils.h"

#include <algorithm>
#include <utility>

#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "cobalt/script/v8c/conversion_helpers.h"
#include "cobalt/script/v8c/native_promise.h"
#include "cobalt/web/environment_settings_helper.h"
#include "starboard/common/murmurhash2.h"

namespace cobalt {
namespace web {
namespace cache_utils {

v8::Local<v8::String> V8String(v8::Isolate* isolate, const std::string& s) {
  return v8::String::NewFromUtf8(isolate, s.c_str())
      .FromMaybe(v8::String::Empty(isolate));
}

std::string FromV8String(v8::Isolate* isolate, v8::Local<v8::Value> value) {
  if (!value->IsString()) {
    return "";
  }
  auto v8_string = value.As<v8::String>();
  std::string result;
  FromJSValue(isolate, v8_string, script::v8c::kNoConversionFlags, nullptr,
              &result);
  return result;
}

base::Optional<v8::Local<v8::Value>> Parse(v8::Isolate* isolate,
                                           const std::string& json) {
  return Evaluate(isolate, "{ const obj = " + json + "; obj; }");
}

base::Optional<v8::Local<v8::Value>> BaseToV8(v8::Isolate* isolate,
                                              const base::Value& value) {
  auto json = std::make_unique<std::string>();
  base::JSONWriter::WriteWithOptions(
      value, base::JSONWriter::OPTIONS_OMIT_BINARY_VALUES, json.get());
  return Parse(isolate, *json);
}

base::Optional<v8::Local<v8::Promise>> OptionalPromise(
    base::Optional<v8::Local<v8::Value>> value) {
  if (!value || !(*value)->IsPromise()) {
    return base::nullopt;
  }
  return value->As<v8::Promise>();
}

std::string Stringify(v8::Isolate* isolate, v8::Local<v8::Value> value) {
  auto global = isolate->GetCurrentContext()->Global();
  Set(global, "___tempObject", value);
  auto result = Evaluate(isolate, "JSON.stringify(___tempObject);");
  Delete(global, "___tempObject");
  if (!result) {
    return "";
  }
  return FromV8String(isolate, result.value());
}

base::Optional<base::Value> Deserialize(const std::string& json) {
  if (json.empty()) {
    return base::nullopt;
  }
  return base::Value::FromUniquePtrValue(base::JSONReader::Read(json));
}

base::Optional<base::Value> V8ToBase(v8::Isolate* isolate,
                                     v8::Local<v8::Value> value) {
  return Deserialize(Stringify(isolate, value));
}

template <typename T>
base::Optional<v8::Local<T>> ToOptional(v8::MaybeLocal<T> value) {
  if (value.IsEmpty()) {
    return base::nullopt;
  }
  return value.ToLocalChecked();
}

v8::Isolate* GetIsolate(v8::Local<v8::Value> object) {
  if (!object->IsObject()) {
    return nullptr;
  }
  return object.As<v8::Object>()->GetIsolate();
}

base::Optional<v8::Local<v8::Value>> GetInternal(v8::Local<v8::Value> object,
                                                 const std::string& path,
                                                 bool parent) {
  auto* isolate = GetIsolate(object);
  if (!isolate) {
    return base::nullopt;
  }

  base::Optional<v8::Local<v8::Value>> curr = object;
  auto context = isolate->GetCurrentContext();
  auto parts = base::SplitString(path, ".", base::TRIM_WHITESPACE,
                                 base::SPLIT_WANT_NONEMPTY);
  int offset = parent ? -1 : 0;
  for (int i = 0; i < parts.size() + offset; i++) {
    if (!curr || !curr.value()->IsObject()) {
      return base::nullopt;
    }
    std::string part = parts[i];
    if (base::ContainsOnlyChars(part, "0123456789")) {
      uint32_t index;
      if (!base::StringToUint32(part, &index)) {
        return base::nullopt;
      }
      curr = ToOptional(curr->As<v8::Object>()->Get(context, index));
    } else {
      curr = ToOptional(
          curr->As<v8::Object>()->Get(context, V8String(isolate, part)));
    }
  }
  return curr;
}

base::Optional<v8::Local<v8::Value>> Get(v8::Local<v8::Value> object,
                                         const std::string& path) {
  return GetInternal(object, path, /*parent=*/false);
}

const base::Value* Get(const base::Value& value, const std::string& path,
                       bool parent) {
  if (!value.is_dict() && !value.is_list()) {
    return nullptr;
  }
  const base::Value* curr = &value;
  auto parts = base::SplitString(path, ".", base::TRIM_WHITESPACE,
                                 base::SPLIT_WANT_NONEMPTY);
  int offset = parent ? -1 : 0;
  for (int i = 0; i < parts.size() + offset; i++) {
    std::string part = parts[i];
    if (curr->is_list()) {
      uint32_t index;
      if (!base::StringToUint32(part, &index)) {
        return nullptr;
      }
      if (index > curr->GetList().size() - 1) {
        return nullptr;
      }
      curr = &curr->GetList()[index];
    } else if (curr->is_dict()) {
      curr = curr->FindKey(part);
    } else {
      return nullptr;
    }
  }
  return curr;
}

template <typename T>
using V8Transform =
    std::function<base::Optional<T>(v8::Isolate*, v8::Local<v8::Value>)>;

struct V8Transforms {
  static base::Optional<double> ToDouble(v8::Isolate* isolate,
                                         v8::Local<v8::Value> value) {
    if (!value->IsNumber()) {
      return base::nullopt;
    }
    return value.As<v8::Number>()->Value();
  }

  static base::Optional<std::string> ToString(v8::Isolate* isolate,
                                              v8::Local<v8::Value> value) {
    if (!value->IsString()) {
      return base::nullopt;
    }
    auto v8_string = value.As<v8::String>();
    std::string result;
    FromJSValue(isolate, v8_string, script::v8c::kNoConversionFlags, nullptr,
                &result);
    return std::move(result);
  }

};  // V8Transforms

template <typename T>
base::Optional<T> Get(v8::Local<v8::Value> object, const std::string& path,
                      V8Transform<T> transform) {
  auto value = GetInternal(object, path, /*parent=*/false);
  if (!value) {
    return base::nullopt;
  }
  return transform(GetIsolate(object), value.value());
}

base::Optional<std::string> GetString(v8::Local<v8::Value> object,
                                      const std::string& path) {
  return Get<std::string>(object, path, V8Transforms::ToString);
}

base::Optional<double> GetNumber(v8::Local<v8::Value> object,
                                 const std::string& path) {
  return Get<double>(object, path, V8Transforms::ToDouble);
}

bool Set(v8::Local<v8::Object> object, const std::string& key,
         v8::Local<v8::Value> value) {
  auto* isolate = object->GetIsolate();
  auto context = isolate->GetCurrentContext();
  auto result = object->Set(context, V8String(isolate, key), value);
  return result.FromMaybe(false);
}

bool Delete(v8::Local<v8::Object> object, const std::string& key) {
  auto* isolate = object->GetIsolate();
  auto context = isolate->GetCurrentContext();
  auto result = object->Delete(context, V8String(isolate, key));
  return result.FromMaybe(false);
}

double FromNumber(v8::Local<v8::Value> value) {
  return value.As<v8::Number>()->Value();
}

v8::Local<v8::Number> ToNumber(v8::Isolate* isolate, double d) {
  return v8::Number::New(isolate, d);
}

std::vector<uint8_t> ToUint8Vector(v8::Local<v8::Value> buffer) {
  if (!buffer->IsArrayBuffer()) {
    return std::vector<uint8_t>();
  }
  auto array_buffer = buffer.As<v8::ArrayBuffer>();
  auto byte_length = array_buffer->ByteLength();
  auto uint8_array =
      v8::Uint8Array::New(array_buffer, /*byte_offset=*/0, byte_length);
  auto vector = std::vector<uint8_t>(byte_length);
  uint8_array->CopyContents(vector.data(), byte_length);
  return std::move(vector);
}

base::Optional<v8::Local<v8::Value>> Call(
    v8::Local<v8::Value> object, const std::string& path,
    std::initializer_list<v8::Local<v8::Value>> args) {
  if (!object->IsObject()) {
    return base::nullopt;
  }
  v8::Local<v8::Value> result;
  auto optional_function = cache_utils::Get(object, path);
  if (!optional_function || !optional_function.value()->IsFunction()) {
    return base::nullopt;
  }
  auto context_object =
      cache_utils::GetInternal(object, path, /*parent=*/true).value();
  auto context =
      context_object.As<v8::Object>()->GetIsolate()->GetCurrentContext();
  const size_t argc = args.size();
  std::vector<v8::Local<v8::Value>> argv = args;
  return ToOptional(optional_function->As<v8::Function>()->Call(
      context, context_object, argv.size(), argv.data()));
}

base::Optional<v8::Local<v8::Value>> Then(v8::Local<v8::Value> value,
                                          OnFullfilled on_fullfilled) {
  if (!value->IsPromise()) {
    on_fullfilled.Reset();
    return base::nullopt;
  }
  auto promise = value.As<v8::Promise>();
  auto* isolate = promise->GetIsolate();
  auto context = isolate->GetCurrentContext();
  auto data = v8::Object::New(isolate);
  Set(data, "promise", promise);
  auto* on_fullfilled_ptr = new OnFullfilled(std::move(on_fullfilled));
  Set(data, "onFullfilled", v8::External::New(isolate, on_fullfilled_ptr));
  auto resulting_promise = promise->Then(
      context,
      v8::Function::New(
          context,
          [](const v8::FunctionCallbackInfo<v8::Value>& info) {
            auto promise = Get(info.Data(), "promise")->As<v8::Promise>();
            auto on_fullfilled = std::unique_ptr<OnFullfilled>(
                static_cast<OnFullfilled*>(Get(info.Data(), "onFullfilled")
                                               ->As<v8::External>()
                                               ->Value()));
            auto optional_resulting_promise =
                std::move(*on_fullfilled).Run(promise);
            if (!optional_resulting_promise) {
              return;
            }
            info.GetReturnValue().Set(optional_resulting_promise.value());
          },
          data)
          .ToLocalChecked(),
      v8::Function::New(
          context,
          [](const v8::FunctionCallbackInfo<v8::Value>& info) {
            auto on_fullfilled = std::unique_ptr<OnFullfilled>(
                static_cast<OnFullfilled*>(Get(info.Data(), "onFullfilled")
                                               ->As<v8::External>()
                                               ->Value()));
            on_fullfilled->Reset();
            info.GetIsolate()->ThrowException(info[0]);
          },
          data)
          .ToLocalChecked());
  if (resulting_promise.IsEmpty()) {
    delete on_fullfilled_ptr;
    return base::nullopt;
  }
  return resulting_promise.ToLocalChecked();
}

void Resolve(v8::Local<v8::Promise::Resolver> resolver,
             v8::Local<v8::Value> value) {
  auto* isolate = resolver->GetIsolate();
  script::v8c::EntryScope entry_scope(isolate);
  auto context = isolate->GetCurrentContext();
  if (value.IsEmpty()) {
    value = v8::Undefined(isolate);
  }
  auto result = resolver->Resolve(context, value);
  DCHECK(result.FromJust());
}

void Reject(v8::Local<v8::Promise::Resolver> resolver) {
  auto* isolate = resolver->GetIsolate();
  script::v8c::EntryScope entry_scope(isolate);
  auto context = isolate->GetCurrentContext();
  auto result = resolver->Reject(context, v8::Undefined(isolate));
  DCHECK(result.FromJust());
}

script::HandlePromiseAny FromResolver(
    v8::Local<v8::Promise::Resolver> resolver) {
  auto* isolate = resolver->GetIsolate();
  return script::HandlePromiseAny(
      new script::v8c::V8cUserObjectHolder<
          script::v8c::NativePromise<script::Any>>(isolate, resolver));
}

void Trace(v8::Isolate* isolate,
           std::initializer_list<v8::Local<v8::Value>> values,
           std::vector<v8::TracedGlobal<v8::Value>*>& traced_globals_out,
           base::OnceClosure& cleanup_traced) {
  auto heap_tracer =
      script::v8c::V8cEngine::GetFromIsolate(isolate)->heap_tracer();
  std::vector<std::unique_ptr<v8::TracedGlobal<v8::Value>>> traced_globals;
  for (auto value : values) {
    auto traced_global =
        std::make_unique<v8::TracedGlobal<v8::Value>>(isolate, value);
    heap_tracer->AddRoot(traced_global.get());
    traced_globals_out.push_back(traced_global.get());
    traced_globals.push_back(std::move(traced_global));
  }
  cleanup_traced = base::BindOnce(
      [](script::v8c::V8cHeapTracer* heap_tracer,
         std::vector<std::unique_ptr<v8::TracedGlobal<v8::Value>>>
             traced_globals) {
        for (int i = 0; i < traced_globals.size(); i++) {
          heap_tracer->RemoveRoot(traced_globals[i].get());
        }
      },
      heap_tracer, std::move(traced_globals));
}

script::Any FromV8Value(v8::Isolate* isolate, v8::Local<v8::Value> value) {
  return script::Any(new script::v8c::V8cValueHandleHolder(isolate, value));
}

v8::Local<v8::Value> ToV8Value(const script::Any& any) {
  return script::GetV8Value(*any.GetScriptValue());
}

base::Optional<v8::Local<v8::Value>> Evaluate(v8::Isolate* isolate,
                                              const std::string& js_code) {
  auto context = isolate->GetCurrentContext();
  auto script = v8::Script::Compile(context, V8String(isolate, js_code));
  if (script.IsEmpty()) {
    return base::nullopt;
  }
  return ToOptional(script.ToLocalChecked()->Run(context));
}

base::Optional<v8::Local<v8::Value>> CreateInstance(
    v8::Isolate* isolate, const std::string& class_name,
    std::initializer_list<v8::Local<v8::Value>> args) {
  auto constructor = Evaluate(isolate, class_name);
  if (!constructor) {
    return base::nullopt;
  }
  auto context = isolate->GetCurrentContext();
  std::vector<v8::Local<v8::Value>> argv = args;
  return ToOptional(constructor.value().As<v8::Function>()->NewInstance(
      context, argv.size(), argv.data()));
}

base::Optional<v8::Local<v8::Value>> CreateRequest(v8::Isolate* isolate,
                                                   const std::string& url,
                                                   const base::Value& options) {
  auto v8_options = v8::Object::New(isolate);
  auto mode = options.FindKey("mode");
  if (mode) {
    Set(v8_options, "mode", V8String(isolate, mode->GetString()));
  }
  auto headers = options.FindKey("headers");
  if (headers) {
    auto v8_headers = v8::Object::New(isolate);
    for (const auto& header : headers->GetList()) {
      const auto& pair = header.GetList();
      DCHECK(pair.size() == 2);
      auto name = pair[0].GetString();
      auto value = pair[1].GetString();
      Set(v8_headers, name, V8String(isolate, value));
    }
    Set(v8_options, "headers", v8_headers);
  }
  return CreateInstance(isolate, "Request",
                        {V8String(isolate, url), v8_options});
}

base::Optional<v8::Local<v8::Value>> CreateResponse(
    v8::Isolate* isolate, const std::vector<uint8_t>& body,
    const base::Value& options) {
  auto status = options.FindKey("status");
  auto status_text = options.FindKey("statusText");
  auto headers = options.FindKey("headers");
  if (body.size() == 0 || !status || !status_text || !headers) {
    return base::nullopt;
  }
  auto v8_body = v8::ArrayBuffer::New(isolate, body.size());
  memcpy(v8_body->GetBackingStore()->Data(), body.data(), body.size());
  auto v8_options = v8::Object::New(isolate);
  Set(v8_options, "status", ToNumber(isolate, status->GetDouble()));
  Set(v8_options, "statusText", V8String(isolate, status_text->GetString()));
  auto v8_headers = v8::Object::New(isolate);
  for (const auto& header : headers->GetList()) {
    const auto& pair = header.GetList();
    DCHECK(pair.size() == 2);
    auto name = pair[0].GetString();
    auto value = pair[1].GetString();
    Set(v8_headers, name, V8String(isolate, value));
  }
  Set(v8_options, "headers", v8_headers);
  return CreateInstance(isolate, "Response", {v8_body, v8_options});
}

base::Optional<base::Value> ExtractResponseOptions(
    v8::Local<v8::Value> response) {
  if (!response->IsObject()) {
    return base::nullopt;
  }
  auto response_object = response.As<v8::Object>();
  auto* isolate = response_object->GetIsolate();
  auto context = isolate->GetCurrentContext();
  auto global = context->Global();
  Set(global, "___tempResponseObject", response_object);
  auto result = Evaluate(isolate,
                         "(() =>"
                         "___tempResponseObject instanceof Response && {"
                         "status: ___tempResponseObject.status,"
                         "statusText: ___tempResponseObject.statusText,"
                         "headers: Array.from(___tempResponseObject.headers),"
                         "}"
                         ")()");
  Delete(global, "___tempResponseObject");
  if (!result) {
    return base::nullopt;
  }
  return V8ToBase(isolate, result.value());
}

uint32_t GetKey(const std::string& s) {
  return starboard::MurmurHash2_32(s.c_str(), s.size());
}

uint32_t GetKey(const GURL& base_url,
                const script::ValueHandleHolder& request_info) {
  return GetKey(GetUrl(base_url, request_info));
}

std::string GetUrl(const GURL& base_url,
                   const script::ValueHandleHolder& request_info) {
  auto v8_value = GetV8Value(request_info);
  auto* isolate = GetIsolate(request_info);
  std::string url;
  if (v8_value->IsString()) {
    url = FromV8String(isolate, v8_value);
  } else {
    // Treat like |Request| and get "url" property.
    auto v8_url = Get(v8_value, "url");
    if (!v8_url) {
      return "";
    }
    url = FromV8String(isolate, v8_url.value());
  }
  GURL::Replacements replacements;
  replacements.ClearUsername();
  replacements.ClearPassword();
  replacements.ClearRef();
  return base_url.Resolve(url).ReplaceComponents(replacements).spec();
}

}  // namespace cache_utils
}  // namespace web
}  // namespace cobalt
