// 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/agent.h"

#include <map>
#include <memory>
#include <utility>

#include "base/observer_list.h"
#include "base/threading/thread_checker.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/base/startup_timer.h"
#include "cobalt/loader/fetcher_factory.h"
#include "cobalt/loader/script_loader_factory.h"
#include "cobalt/script/environment_settings.h"
#include "cobalt/script/error_report.h"
#include "cobalt/script/execution_state.h"
#include "cobalt/script/global_environment.h"
#include "cobalt/script/javascript_engine.h"
#include "cobalt/script/script_runner.h"
#include "cobalt/script/wrappable.h"
#include "cobalt/web/blob.h"
#include "cobalt/web/context.h"
#include "cobalt/web/environment_settings.h"
#include "cobalt/web/url.h"
#include "cobalt/web/window_or_worker_global_scope.h"
#include "cobalt/worker/service_worker.h"
#include "cobalt/worker/service_worker_jobs.h"
#include "cobalt/worker/service_worker_object.h"
#include "cobalt/worker/service_worker_registration.h"
#include "cobalt/worker/service_worker_registration_object.h"

namespace cobalt {
namespace web {
// Private Web Context implementation. Each Agent owns a single instance of
// this class, which performs all the actual work. All functions of this class
// must be called on the message loop of the Agent thread, so they
// execute synchronously with respect to one another.
namespace {
class Impl : public Context {
 public:
  Impl(const std::string& name, const Agent::Options& options);
  virtual ~Impl();

  void AddEnvironmentSettingsChangeObserver(
      EnvironmentSettingsChangeObserver* observer) final;
  void RemoveEnvironmentSettingsChangeObserver(
      EnvironmentSettingsChangeObserver* observer) final;

  // Context
  //
  void set_message_loop(base::MessageLoop* message_loop) {
    message_loop_ = message_loop;
  }
  base::MessageLoop* message_loop() const final { return message_loop_; }
  void ShutDownJavaScriptEngine() final;
  loader::FetcherFactory* fetcher_factory() const final {
    return fetcher_factory_.get();
  }
  loader::ScriptLoaderFactory* script_loader_factory() const final {
    return script_loader_factory_.get();
  }
  script::JavaScriptEngine* javascript_engine() const final {
    return javascript_engine_.get();
  }
  script::GlobalEnvironment* global_environment() const final {
    return global_environment_.get();
  }
  script::ExecutionState* execution_state() const final {
    return execution_state_.get();
  }
  script::ScriptRunner* script_runner() const final {
    return script_runner_.get();
  }
  Blob::Registry* blob_registry() const final { return blob_registry_.get(); }
  web::WebSettings* web_settings() const final { return web_settings_; }
  network::NetworkModule* network_module() const final {
    DCHECK(fetcher_factory_);
    return fetcher_factory_->network_module();
  }
  worker::ServiceWorkerJobs* service_worker_jobs() const final {
    return service_worker_jobs_;
  }

  const std::string& name() const final { return name_; };
  void SetupEnvironmentSettings(
      EnvironmentSettings* environment_settings) final {
    for (auto& observer : environment_settings_change_observers_) {
      observer.OnEnvironmentSettingsChanged(!!environment_settings);
    }
    environment_settings_.reset(environment_settings);
    if (environment_settings_) {
      environment_settings_->set_context(this);
    }
  }

  void SetupFinished();

  EnvironmentSettings* environment_settings() const final {
    DCHECK(environment_settings_);
    DCHECK_EQ(environment_settings_->context(), this);
    return environment_settings_.get();
  }

  scoped_refptr<worker::ServiceWorkerRegistration>
  LookupServiceWorkerRegistration(
      worker::ServiceWorkerRegistrationObject* registration) final;
  // https://www.w3.org/TR/2022/CRD-service-workers-20220712/#service-worker-registration-creation
  scoped_refptr<worker::ServiceWorkerRegistration> GetServiceWorkerRegistration(
      worker::ServiceWorkerRegistrationObject* registration) final;

  void RemoveServiceWorker(worker::ServiceWorkerObject* worker) final;
  scoped_refptr<worker::ServiceWorker> LookupServiceWorker(
      worker::ServiceWorkerObject* worker) final;
  // https://www.w3.org/TR/2022/CRD-service-workers-20220712/#get-the-service-worker-object
  scoped_refptr<worker::ServiceWorker> GetServiceWorker(
      worker::ServiceWorkerObject* worker) final;

  WindowOrWorkerGlobalScope* GetWindowOrWorkerGlobalScope() final;

  const UserAgentPlatformInfo* platform_info() const final {
    return platform_info_;
  }
  std::string GetUserAgent() const final {
    return network_module()->GetUserAgent();
  }
  std::string GetPreferredLanguage() const final {
    return network_module()->preferred_language();
  }

  // https://www.w3.org/TR/2022/CRD-service-workers-20220712/#dfn-control
  bool is_controlled_by(worker::ServiceWorkerObject* worker) const final {
    // When a service worker client has a non-null active service worker, it is
    // said to be controlled by that active service worker.
    return active_service_worker() && (active_service_worker() == worker);
  }

  // https://html.spec.whatwg.org/multipage/webappapis.html#concept-environment-active-service-worker
  void set_active_service_worker(
      const scoped_refptr<worker::ServiceWorkerObject>& worker) final {
    active_service_worker_ = worker;
  }
  const scoped_refptr<worker::ServiceWorkerObject>& active_service_worker()
      const final {
    return active_service_worker_;
  }
  scoped_refptr<worker::ServiceWorkerObject>& active_service_worker() final {
    return active_service_worker_;
  }


 private:
  // Injects a list of attributes into the Web Context's global object.
  void InjectGlobalObjectAttributes(
      const Agent::Options::InjectedGlobalObjectAttributes& attributes);

  // Thread checker ensures all calls to the Context are made from the same
  // thread that it is created in.
  THREAD_CHECKER(thread_checker_);

  // The message loop for the web context.
  base::MessageLoop* message_loop_ = nullptr;

  // Name of the web instance.
  std::string name_;

  web::WebSettings* const web_settings_;

  // FetcherFactory that is used to create a fetcher according to URL.
  std::unique_ptr<loader::FetcherFactory> fetcher_factory_;

  // Todo: b/225410588 This is not used by WebModule. Should live in a
  // better place.
  // LoaderFactory that is used to acquire references to resources from a URL.
  std::unique_ptr<loader::ScriptLoaderFactory> script_loader_factory_;

  // JavaScript engine for the browser.
  std::unique_ptr<script::JavaScriptEngine> javascript_engine_;

  // JavaScript Global Object for the browser. There should be one per window,
  // but since there is only one window, we can have one per browser.
  scoped_refptr<script::GlobalEnvironment> global_environment_;

  // Used by |Console| to obtain a JavaScript stack trace.
  std::unique_ptr<script::ExecutionState> execution_state_;

  // Interface for the document to execute JavaScript code.
  std::unique_ptr<script::ScriptRunner> script_runner_;

  // Object to register and retrieve Blob objects with a string key.
  std::unique_ptr<Blob::Registry> blob_registry_;

  // Environment Settings object
  std::unique_ptr<EnvironmentSettings> environment_settings_;

  // The service worker registration object map.
  //   https://www.w3.org/TR/2022/CRD-service-workers-20220712/#environment-settings-object-service-worker-registration-object-map
  std::map<worker::ServiceWorkerRegistrationObject*,
           scoped_refptr<worker::ServiceWorkerRegistration>>
      service_worker_registration_object_map_;

  // The service worker object map.
  //   https://www.w3.org/TR/2022/CRD-service-workers-20220712/#environment-settings-object-service-worker-object-map
  std::map<worker::ServiceWorkerObject*, scoped_refptr<worker::ServiceWorker>>
      service_worker_object_map_;

  worker::ServiceWorkerJobs* service_worker_jobs_;
  const web::UserAgentPlatformInfo* platform_info_;

  // https://html.spec.whatwg.org/multipage/webappapis.html#concept-environment-active-service-worker
  // Note: When a service worker is unregistered from the last client, this will
  // hold the last reference until the current page is unloaded.
  scoped_refptr<worker::ServiceWorkerObject> active_service_worker_;

  base::ObserverList<Context::EnvironmentSettingsChangeObserver>::Unchecked
      environment_settings_change_observers_;
};

void LogScriptError(const base::SourceLocation& source_location,
                    const std::string& error_message) {
  std::string file_name =
      base::FilePath(source_location.file_path).BaseName().value();

  std::stringstream ss;
  base::TimeDelta dt = base::StartupTimer::TimeElapsed();

  // Create the error output.
  // Example:
  //   JS:50250:file.js(29,80): ka(...) is not iterable
  //   JS:<time millis><js-file-name>(<line>,<column>):<message>
  ss << "JS:" << dt.InMilliseconds() << ":" << file_name << "("
     << source_location.line_number << "," << source_location.column_number
     << "): " << error_message << "\n";
  SbLogRaw(ss.str().c_str());
}

Impl::Impl(const std::string& name, const Agent::Options& options)
    : name_(name), web_settings_(options.web_settings) {
  TRACE_EVENT0("cobalt::web", "Agent::Impl::Impl()");
  service_worker_jobs_ = options.service_worker_jobs;
  platform_info_ = options.platform_info;
  blob_registry_.reset(new Blob::Registry);

  fetcher_factory_.reset(new loader::FetcherFactory(
      options.network_module, options.extra_web_file_dir,
      URL::MakeBlobResolverCallback(blob_registry_.get()),
      options.read_cache_callback));
  DCHECK(fetcher_factory_);

  script_loader_factory_.reset(new loader::ScriptLoaderFactory(
      name.c_str(), fetcher_factory_.get(), options.thread_priority));
  DCHECK(script_loader_factory_);

  javascript_engine_ =
      script::JavaScriptEngine::CreateEngine(options.javascript_engine_options);
  DCHECK(javascript_engine_);

#if defined(COBALT_ENABLE_JAVASCRIPT_ERROR_LOGGING)
  script::JavaScriptEngine::ErrorHandler error_handler =
      base::Bind(&LogScriptError);
  javascript_engine_->RegisterErrorHandler(error_handler);
#endif

  global_environment_ = javascript_engine_->CreateGlobalEnvironment();
  DCHECK(global_environment_);

  global_environment_->AddRoot(blob_registry_.get());

  execution_state_ =
      script::ExecutionState::CreateExecutionState(global_environment_);
  DCHECK(execution_state_);

  script_runner_ =
      script::ScriptRunner::CreateScriptRunner(global_environment_);
  DCHECK(script_runner_);

  // Schedule the injected global attributes to be added later, to ensure they
  // are added after the global object is created.
  if (!options.injected_global_object_attributes.empty()) {
    DCHECK(base::MessageLoop::current());
    base::MessageLoop::current()->task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&Impl::InjectGlobalObjectAttributes, base::Unretained(this),
                   options.injected_global_object_attributes));
  }
}

void Impl::ShutDownJavaScriptEngine() {
  // TODO: Disentangle shutdown of the JS engine with the various tracking and
  // caching in the WebModule.

  set_active_service_worker(nullptr);
  service_worker_object_map_.clear();
  service_worker_registration_object_map_.clear();

  if (global_environment_) {
    global_environment_->SetReportEvalCallback(base::Closure());
    global_environment_->SetReportErrorCallback(
        script::GlobalEnvironment::ReportErrorCallback());
  }

  SetupEnvironmentSettings(nullptr);
  environment_settings_change_observers_.Clear();
  blob_registry_.reset();
  script_runner_.reset();
  execution_state_.reset();

  // Ensure that global_environment_ is null before it's destroyed.
  scoped_refptr<script::GlobalEnvironment> global_environment(
      std::move(global_environment_));
  DCHECK(!global_environment_);
  global_environment = nullptr;

  javascript_engine_.reset();
  fetcher_factory_.reset();
  script_loader_factory_.reset();
}

Impl::~Impl() { ShutDownJavaScriptEngine(); }

void Impl::AddEnvironmentSettingsChangeObserver(
    Context::EnvironmentSettingsChangeObserver* observer) {
  environment_settings_change_observers_.AddObserver(observer);
}

void Impl::RemoveEnvironmentSettingsChangeObserver(
    Context::EnvironmentSettingsChangeObserver* observer) {
  environment_settings_change_observers_.RemoveObserver(observer);
}

void Impl::SetupFinished() {
  auto* global_scope = GetWindowOrWorkerGlobalScope();
#if !defined(COBALT_FORCE_CSP)
  if (global_scope && global_scope->options().csp_options.enforcement_type ==
                          web::kCspEnforcementDisable) {
    // If CSP is disabled, enable eval(). Otherwise, it will be enabled by
    // a CSP directive.
    global_environment_->EnableEval();
  }
#endif

  if (service_worker_jobs_) {
    service_worker_jobs_->RegisterWebContext(this);
  }
  if (service_worker_jobs_) {
    service_worker_jobs_->SetActiveWorker(environment_settings_.get());
  }
}


void Impl::InjectGlobalObjectAttributes(
    const Agent::Options::InjectedGlobalObjectAttributes& attributes) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(global_environment_);

  for (Agent::Options::InjectedGlobalObjectAttributes::const_iterator iter =
           attributes.begin();
       iter != attributes.end(); ++iter) {
    global_environment_->Bind(iter->first,
                              iter->second.Run(environment_settings()));
  }
}

scoped_refptr<worker::ServiceWorkerRegistration>
Impl::LookupServiceWorkerRegistration(
    worker::ServiceWorkerRegistrationObject* registration) {
  scoped_refptr<worker::ServiceWorkerRegistration> worker_registration;
  if (!registration) {
    return worker_registration;
  }
  auto registration_lookup =
      service_worker_registration_object_map_.find(registration);
  if (registration_lookup != service_worker_registration_object_map_.end()) {
    worker_registration = registration_lookup->second;
  }
  return worker_registration;
}

scoped_refptr<worker::ServiceWorkerRegistration>
Impl::GetServiceWorkerRegistration(
    worker::ServiceWorkerRegistrationObject* registration) {
  // Algorithm for 'get the service worker registration object':
  //   https://www.w3.org/TR/2022/CRD-service-workers-20220712/#get-the-service-worker-registration-object
  scoped_refptr<worker::ServiceWorkerRegistration> worker_registration;
  if (!registration) {
    // Return undefined when registration is null.
    return worker_registration;
  }

  // 1. Let objectMap be environment’s service worker registration object map.
  // 2. If objectMap[registration] does not exist, then:
  auto registration_lookup =
      service_worker_registration_object_map_.find(registration);
  if (registration_lookup == service_worker_registration_object_map_.end()) {
    // 2.1. Let registrationObject be a new ServiceWorkerRegistration in
    // environment’s Realm.
    // 2.2. Set registrationObject’s service worker registration to
    // registration.
    // 2.3. Set registrationObject’s installing attribute to null.
    // 2.4. Set registrationObject’s waiting attribute to null.
    // 2.5. Set registrationObject’s active attribute to null.
    worker_registration = new worker::ServiceWorkerRegistration(
        environment_settings(), registration);

    // 2.6. If registration’s installing worker is not null, then set
    // registrationObject’s installing attribute to the result of getting the
    // service worker object that represents registration’s installing worker in
    // environment.
    if (registration->installing_worker()) {
      worker_registration->set_installing(
          GetServiceWorker(registration->installing_worker()));
    }

    // 2.7. If registration’s waiting worker is not null, then set
    // registrationObject’s waiting attribute to the result of getting the
    // service worker object that represents registration’s waiting worker in
    // environment.
    if (registration->waiting_worker()) {
      worker_registration->set_waiting(
          GetServiceWorker(registration->waiting_worker()));
    }

    // 2.8. If registration’s active worker is not null, then set
    // registrationObject’s active attribute to the result of getting the
    // service worker object that represents registration’s active worker in
    // environment.
    if (registration->active_worker()) {
      worker_registration->set_active(
          GetServiceWorker(registration->active_worker()));
    }

    // 2.9. Set objectMap[registration] to registrationObject.
    service_worker_registration_object_map_.insert(
        std::make_pair(registration, worker_registration));
  } else {
    worker_registration = registration_lookup->second;
  }
  // 3. Return objectMap[registration].
  return worker_registration;
}


void Impl::RemoveServiceWorker(worker::ServiceWorkerObject* worker) {
  service_worker_object_map_.erase(worker);
}

scoped_refptr<worker::ServiceWorker> Impl::LookupServiceWorker(
    worker::ServiceWorkerObject* worker) {
  // Algorithm for 'get the service worker object':
  //   https://www.w3.org/TR/2022/CRD-service-workers-20220712/#get-the-service-worker-object
  scoped_refptr<worker::ServiceWorker> service_worker;

  if (!worker) {
    // Return undefined when worker is null.
    return service_worker;
  }

  // 1. Let objectMap be environment’s service worker object map.
  // 2. If objectMap[serviceWorker] does not exist, then:
  auto worker_lookup = service_worker_object_map_.find(worker);
  if (worker_lookup != service_worker_object_map_.end()) {
    service_worker = worker_lookup->second;
  }
  return service_worker;
}

scoped_refptr<worker::ServiceWorker> Impl::GetServiceWorker(
    worker::ServiceWorkerObject* worker) {
  // Algorithm for 'get the service worker object':
  //   https://www.w3.org/TR/2022/CRD-service-workers-20220712/#get-the-service-worker-object
  scoped_refptr<worker::ServiceWorker> service_worker;

  if (!worker) {
    // Return undefined when worker is null.
    return service_worker;
  }

  // 1. Let objectMap be environment’s service worker object map.
  // 2. If objectMap[serviceWorker] does not exist, then:
  auto worker_lookup = service_worker_object_map_.find(worker);
  if (worker_lookup == service_worker_object_map_.end()) {
    // 2.1. Let serviceWorkerObj be a new ServiceWorker in environment’s Realm,
    // and associate it with serviceWorker.
    // 2.2. Set serviceWorkerObj’s state to serviceWorker’s state.
    service_worker = new worker::ServiceWorker(environment_settings(), worker);

    // 2.3. Set objectMap[serviceWorker] to serviceWorkerObj.
    service_worker_object_map_.insert(std::make_pair(worker, service_worker));
  } else {
    service_worker = worker_lookup->second;
  }

  // 3. Return objectMap[serviceWorker].
  return service_worker;
}

WindowOrWorkerGlobalScope* Impl::GetWindowOrWorkerGlobalScope() {
  script::Wrappable* global_wrappable =
      global_environment_ ? global_environment_->global_wrappable() : nullptr;
  if (!global_wrappable) {
    return nullptr;
  }
  DCHECK(global_wrappable->IsWrappable());
  DCHECK_EQ(script::Wrappable::JSObjectType::kObject,
            global_wrappable->GetJSObjectType());

  return base::polymorphic_downcast<WindowOrWorkerGlobalScope*>(
      global_wrappable);
}

// Signals the given WaitableEvent.
void SignalWaitableEvent(base::WaitableEvent* event) { event->Signal(); }
}  // namespace

void Agent::WillDestroyCurrentMessageLoop() { context_.reset(); }

Agent::Agent(const std::string& name) : thread_(name) {}

void Agent::Stop() {
  DCHECK(message_loop());
  DCHECK(thread_.IsRunning());

  if (context() && context()->service_worker_jobs()) {
    context()->service_worker_jobs()->UnregisterWebContext(context());
  }

  // Ensure that the destruction observer got added before stopping the thread.
  destruction_observer_added_.Wait();
  // Stop the thread. This will cause the destruction observer to be notified.
  thread_.Stop();
}

Agent::~Agent() {
  DCHECK(!thread_.IsRunning());
  if (thread_.IsRunning()) {
    Stop();
  }
}

void Agent::Run(const Options& options, InitializeCallback initialize_callback,
                DestructionObserver* destruction_observer) {
  // Start the dedicated thread and create the internal implementation
  // object on that thread.
  base::Thread::Options thread_options(base::MessageLoop::TYPE_DEFAULT,
                                       options.stack_size);
  thread_options.priority = options.thread_priority;
  if (!thread_.StartWithOptions(thread_options)) return;
  DCHECK(message_loop());

  message_loop()->task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&Agent::InitializeTaskInThread, base::Unretained(this),
                 options, initialize_callback));

  if (destruction_observer) {
    message_loop()->task_runner()->PostTask(
        FROM_HERE, base::Bind(&base::MessageLoop::AddDestructionObserver,
                              base::Unretained(message_loop()),
                              base::Unretained(destruction_observer)));
  }
  // Register as a destruction observer to shut down the Web Agent once all
  // pending tasks have been executed and the message loop is about to be
  // destroyed. This allows us to safely stop the thread, drain the task queue,
  // then destroy the internal components before the message loop is reset.
  // No posted tasks will be executed once the thread is stopped.
  message_loop()->task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&base::MessageLoop::AddDestructionObserver,
                 base::Unretained(message_loop()), base::Unretained(this)));

  // This works almost like a PostBlockingTask, except that any blocking that
  // may be necessary happens when Stop() is called instead of right now.
  message_loop()->task_runner()->PostTask(
      FROM_HERE, base::Bind(&SignalWaitableEvent,
                            base::Unretained(&destruction_observer_added_)));
}

void Agent::InitializeTaskInThread(const Options& options,
                                   InitializeCallback initialize_callback) {
  DCHECK_EQ(base::MessageLoop::current(), message_loop());
  context_.reset(
      CreateContext(thread_.thread_name(), options, thread_.message_loop()));
  initialize_callback.Run(context_.get());
}

Context* Agent::CreateContext(const std::string& name, const Options& options,
                              base::MessageLoop* message_loop) {
  auto* context = new Impl(name, options);
  context->set_message_loop(message_loop);
  return context;
}

void Agent::WaitUntilDone() {
  DCHECK(message_loop());
  if (base::MessageLoop::current() != message_loop()) {
    message_loop()->task_runner()->PostBlockingTask(
        FROM_HERE, base::Bind(&Agent::WaitUntilDone, base::Unretained(this)));
    return;
  }
  DCHECK_EQ(base::MessageLoop::current(), message_loop());
}

void Agent::RequestJavaScriptHeapStatistics(
    const JavaScriptHeapStatisticsCallback& callback) {
  TRACE_EVENT0("cobalt::web", "Agent::RequestJavaScriptHeapStatistics()");
  DCHECK(message_loop());
  if (base::MessageLoop::current() != message_loop()) {
    message_loop()->task_runner()->PostTask(
        FROM_HERE, base::Bind(&Agent::RequestJavaScriptHeapStatistics,
                              base::Unretained(this), callback));
    return;
  }
  script::HeapStatistics heap_statistics =
      context_->javascript_engine()->GetHeapStatistics();
  callback.Run(heap_statistics);
}

}  // namespace web
}  // namespace cobalt
