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

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "fxjs/js_define.h"

#include <math.h>
#include <stdarg.h>

#include <algorithm>
#include <limits>
#include <vector>

#include "core/fxcrt/fx_extension.h"
#include "fxjs/cjs_document.h"
#include "fxjs/cjs_object.h"
#include "fxjs/fx_date_helpers.h"
#include "fxjs/fxv8.h"
#include "third_party/base/check.h"

void JSDestructor(v8::Local<v8::Object> obj) {
  CFXJS_Engine::SetObjectPrivate(obj, nullptr);
}

double JS_DateParse(const WideString& str) {
  v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::HandleScope scope(pIsolate);

  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();

  // Use the built-in object method.
  v8::MaybeLocal<v8::Value> maybe_value =
      context->Global()->Get(context, fxv8::NewStringHelper(pIsolate, "Date"));

  v8::Local<v8::Value> value;
  if (!maybe_value.ToLocal(&value) || !value->IsObject())
    return 0;

  v8::Local<v8::Object> obj = value.As<v8::Object>();
  maybe_value = obj->Get(context, fxv8::NewStringHelper(pIsolate, "parse"));
  if (!maybe_value.ToLocal(&value) || !value->IsFunction())
    return 0;

  v8::Local<v8::Function> func = value.As<v8::Function>();
  static constexpr int argc = 1;
  v8::Local<v8::Value> argv[argc] = {
      fxv8::NewStringHelper(pIsolate, str.AsStringView()),
  };
  maybe_value = func->Call(context, context->Global(), argc, argv);
  if (!maybe_value.ToLocal(&value) || !value->IsNumber())
    return 0;

  double date = value.As<v8::Number>()->Value();
  return isfinite(date) ? FX_LocalTime(date) : date;
}

std::vector<v8::Local<v8::Value>> ExpandKeywordParams(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& originals,
    size_t nKeywords,
    ...) {
  DCHECK(nKeywords);

  std::vector<v8::Local<v8::Value>> result(nKeywords, v8::Local<v8::Value>());
  size_t size = std::min(originals.size(), nKeywords);
  for (size_t i = 0; i < size; ++i)
    result[i] = originals[i];

  if (originals.size() != 1 || !originals[0]->IsObject() ||
      originals[0]->IsArray()) {
    return result;
  }
  result[0] = v8::Local<v8::Value>();  // Make unknown.

  v8::Local<v8::Object> pObj = pRuntime->ToObject(originals[0]);
  va_list ap;
  va_start(ap, nKeywords);
  for (size_t i = 0; i < nKeywords; ++i) {
    const char* property = va_arg(ap, const char*);
    v8::Local<v8::Value> v8Value = pRuntime->GetObjectProperty(pObj, property);
    if (!v8Value->IsUndefined())
      result[i] = v8Value;
  }
  va_end(ap);

  return result;
}

bool IsExpandedParamKnown(v8::Local<v8::Value> value) {
  return !value.IsEmpty() &&
         (value->IsString() || value->IsNumber() || value->IsBoolean() ||
          value->IsDate() || value->IsObject() || value->IsNull() ||
          value->IsUndefined());
}
