// Copyright 2018 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/dom/screenshot_manager.h"

#include <memory>
#include <utility>

#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "cobalt/dom/screenshot.h"
#include "cobalt/render_tree/node.h"
#include "cobalt/render_tree/resource_provider_stub.h"
#include "cobalt/script/array_buffer.h"
#include "cobalt/web/context.h"
#include "cobalt/web/environment_settings.h"

namespace cobalt {
namespace dom {

ScreenshotManager::ScreenshotManager(
    script::EnvironmentSettings* settings,
    const ScreenshotManager::ProvideScreenshotFunctionCallback&
        screenshot_function_callback)
    : environment_settings_(settings),
      screenshot_function_callback_(screenshot_function_callback) {}

void ScreenshotManager::Screenshot(
    loader::image::EncodedStaticImage::ImageFormat desired_format,
    const scoped_refptr<render_tree::Node>& render_tree_root,
    std::unique_ptr<ScreenshotManager::InterfacePromiseValue::Reference>
        promise_reference) {
  DLOG(INFO) << "Will take a screenshot asynchronously";
  DCHECK(!screenshot_function_callback_.is_null());

  // We want to ScreenshotManager::FillScreenshot, on this thread.
  base::Callback<void(std::unique_ptr<uint8[]>, const math::Size&)>
      fill_screenshot = base::Bind(
          &ScreenshotManager::FillScreenshot, base::Unretained(this),
          next_ticket_id_, base::ThreadTaskRunnerHandle::Get(), desired_format);
  bool was_emplaced =
      ticket_to_screenshot_promise_map_
          .emplace(next_ticket_id_, std::move(promise_reference))
          .second;
  DCHECK(was_emplaced);
  ++next_ticket_id_;

  screenshot_function_callback_.Run(
      render_tree_root, /*clip_rect=*/base::nullopt, fill_screenshot);
}

void ScreenshotManager::FillScreenshot(
    int64_t token,
    scoped_refptr<base::SingleThreadTaskRunner> expected_task_runner,
    loader::image::EncodedStaticImage::ImageFormat desired_format,
    std::unique_ptr<uint8[]> image_data, const math::Size& image_dimensions) {
  if (expected_task_runner && !expected_task_runner->BelongsToCurrentThread()) {
    expected_task_runner->PostTask(
        FROM_HERE,
        base::Bind(&ScreenshotManager::FillScreenshot, base::Unretained(this),
                   token, expected_task_runner, desired_format,
                   base::Passed(&image_data), image_dimensions));
    return;
  }
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(environment_settings_);

  auto iterator = ticket_to_screenshot_promise_map_.find(token);
  DCHECK(iterator != ticket_to_screenshot_promise_map_.end());
  const script::Promise<scoped_refptr<script::Wrappable>>& promise =
      iterator->second->value();
  do {
    if (!image_data) {
      // There was no data for the screenshot.
      LOG(WARNING) << "There was no data for the screenshot.";
      promise.Reject();
      break;
    }

    scoped_refptr<loader::image::EncodedStaticImage> encoded_image_data =
        CompressRGBAImage(desired_format, image_data.get(), image_dimensions);

    size_t encoded_size = encoded_image_data->GetEstimatedSizeInBytes();

    if (encoded_image_data->GetEstimatedSizeInBytes() > kint32max) {
      NOTREACHED();
      promise.Reject();
      break;
    }
    DLOG(INFO) << "Filling data in for the screenshot.";
    script::Handle<script::ArrayBuffer> pixel_data = script::ArrayBuffer::New(
        base::polymorphic_downcast<web::EnvironmentSettings*>(
            environment_settings_)
            ->context()
            ->global_environment(),
        encoded_image_data->GetMemory(), encoded_size);
    scoped_refptr<script::Wrappable> promise_result =
        new dom::Screenshot(pixel_data);
    promise.Resolve(promise_result);
  } while (0);

  DCHECK(promise.State() != script::PromiseState::kPending);
  // Drop the reference to the promise since it will not be used.
  ticket_to_screenshot_promise_map_.erase(iterator);
}

}  // namespace dom
}  // namespace cobalt
