// Copyright 2023 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/js_profiler/profiler.h"

#include <limits>
#include <memory>
#include <string>
#include <utility>

#include "base/logging.h"
#include "cobalt/js_profiler/profiler_trace_wrapper.h"
#include "cobalt/web/cache_utils.h"
#include "cobalt/web/context.h"
#include "cobalt/web/dom_exception.h"
#include "cobalt/web/environment_settings_helper.h"

namespace cobalt {
namespace js_profiler {

Profiler::Profiler(script::EnvironmentSettings* settings,
                   ProfilerInitOptions options,
                   script::ExceptionState* exception_state)
    : stopped_(false), time_origin_{base::TimeTicks::Now()} {
  profiler_group_ = ProfilerGroup::From(settings);
  profiler_id_ = profiler_group_->NextProfilerId();

  const base::TimeDelta sample_interval =
      base::Milliseconds(options.sample_interval());

  int64_t sample_interval_us = sample_interval.InMicroseconds();

  if (sample_interval_us < 0 ||
      sample_interval_us > std::numeric_limits<int>::max()) {
    sample_interval_us = 0;
  }

  int effective_sample_interval_ms =
      static_cast<int>(sample_interval.InMilliseconds());
  if (effective_sample_interval_ms % Profiler::kBaseSampleIntervalMs != 0 ||
      effective_sample_interval_ms == 0) {
    effective_sample_interval_ms +=
        (Profiler::kBaseSampleIntervalMs -
         effective_sample_interval_ms % Profiler::kBaseSampleIntervalMs);
  }
  sample_interval_ = effective_sample_interval_ms;

  SB_LOG(INFO) << "[PROFILER] START " + profiler_id_;
  auto status = profiler_group_->ProfilerStart(
      this, settings,
      v8::CpuProfilingOptions(v8::kLeafNodeLineNumbers,
                              options.max_buffer_size(), sample_interval_us));

  if (status == v8::CpuProfilingStatus::kAlreadyStarted) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             "Profiler Already started", exception_state);
  } else if (status == v8::CpuProfilingStatus::kErrorTooManyProfilers) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             "Too Many Profilers", exception_state);
  }
}

void Profiler::AddEventListener(
    script::EnvironmentSettings* environment_settings, const std::string& name,
    const Profiler::SampleBufferFullCallbackHolder& holder) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  if (name != base::Tokens::samplebufferfull()) {
    return;
  }
  auto* global_wrappable = web::get_global_wrappable(environment_settings);
  SampleBufferFullCallbackReference* token_callback =
      new SampleBufferFullCallbackReference(global_wrappable, holder);
  listeners_.push_back(
      std::unique_ptr<SampleBufferFullCallbackReference>(token_callback));
}

void Profiler::DispatchSampleBufferFullEvent() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  for (auto it = listeners_.begin(); it != listeners_.end(); ++it) {
    (*it)->value().Run();
  }
  listeners_.clear();
}

Profiler::ProfilerTracePromise Profiler::Stop(
    script::EnvironmentSettings* environment_settings) {
  SB_LOG(INFO) << "[PROFILER] STOPPING " + profiler_id_;
  script::HandlePromiseWrappable promise =
      web::get_script_value_factory(environment_settings)
          ->CreateInterfacePromise<scoped_refptr<ProfilerTraceWrapper>>();
  if (!stopped()) {
    stopped_ = true;
    auto* global_wrappable = web::get_global_wrappable(environment_settings);
    auto* context = web::get_context(environment_settings);
    std::unique_ptr<script::ValuePromiseWrappable::Reference> promise_reference(
        new script::ValuePromiseWrappable::Reference(global_wrappable,
                                                     promise));

    context->message_loop()->task_runner()->PostTask(
        FROM_HERE,
        base::BindOnce(&Profiler::PerformStop, base::Unretained(this),
                       profiler_group_, std::move(promise_reference),
                       std::move(time_origin_), std::move(profiler_id_)));
  } else {
    promise->Reject(new web::DOMException(web::DOMException::kInvalidStateErr,
                                          "Profiler already stopped."));
  }
  return promise;
}

void Profiler::PerformStop(
    ProfilerGroup* profiler_group,
    std::unique_ptr<script::ValuePromiseWrappable::Reference> promise_reference,
    base::TimeTicks time_origin, std::string profiler_id) {
  SB_LOG(INFO) << "[PROFILER] STOPPED " + profiler_id_;
  auto trace = profiler_group->ProfilerStop(this);
  scoped_refptr<ProfilerTraceWrapper> result(new ProfilerTraceWrapper(trace));
  promise_reference->value().Resolve(result);
}

void Profiler::Cancel() {
  if (!stopped_) {
    stopped_ = true;
    profiler_group_->ProfilerStop(this);
  }
  profiler_group_ = nullptr;
}

}  // namespace js_profiler
}  // namespace cobalt
