// Copyright 2016 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 <memory>

#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/base/wrap_main.h"
#include "cobalt/loader/image/image_decoder.h"
#include "cobalt/math/size.h"
#include "cobalt/renderer/renderer_module.h"
#include "cobalt/system_window/system_window.h"
#include "cobalt/trace_event/scoped_trace_to_file.h"

namespace cobalt {
namespace loader {
namespace image {
namespace sandbox {
namespace {
const int kViewportWidth = 1920;
const int kViewportHeight = 1080;

using base::FileEnumerator;
using render_tree::ResourceProvider;
using renderer::RendererModule;
using system_window::SystemWindow;

struct ImageDecoderCallback {
  void SuccessCallback(const scoped_refptr<loader::image::Image>& value) {
    image = value;
  }

  void LoadCompleteCallback(const base::Optional<std::string>& error) {
    if (error) LOG(ERROR) << *error;
  }

  scoped_refptr<loader::image::Image> image;
};

std::vector<base::FilePath> GetImagePaths(const char* extention) {
  base::FilePath image_path;
  CHECK(base::PathService::Get(base::DIR_TEST_DATA, &image_path));
  image_path = image_path.Append(FILE_PATH_LITERAL("cobalt"))
                   .Append(FILE_PATH_LITERAL("loader"))
                   .Append(FILE_PATH_LITERAL("testdata"));

  std::vector<base::FilePath> result;
  FileEnumerator file_enumerator(image_path, false /* Not recursive */,
                                 FileEnumerator::FILES);
  for (base::FilePath next = file_enumerator.Next(); !next.empty();
       next = file_enumerator.Next()) {
    if (next.Extension() == extention) {
      result.push_back(next);
    }
  }
  return result;
}

std::vector<uint8> GetFileContent(const base::FilePath& file_path) {
  int64 size;
  std::vector<uint8> data;

  bool success = base::GetFileSize(file_path, &size);

  CHECK(success) << "Could not get file size.";
  CHECK_GT(size, 0);

  data.resize(static_cast<size_t>(size));

  int num_of_bytes = base::ReadFile(
      file_path, reinterpret_cast<char*>(&data[0]), static_cast<int>(size));

  CHECK_EQ(num_of_bytes, data.size())
      << "Could not read '" << file_path.value() << "'.";
  return data;
}

void DecodeImages(ResourceProvider* resource_provider, const char* extension) {
  std::vector<base::FilePath> paths = GetImagePaths(extension);
  base::TimeDelta total_time;
  size_t total_size = 0;

  for (size_t i = 0; i < paths.size(); ++i) {
    base::NullDebuggerHooks debugger_hooks;
    ImageDecoderCallback image_decoder_result;
    std::vector<uint8> image_data = GetFileContent(paths[i]);

    base::Time start = base::Time::Now();
    std::unique_ptr<Decoder> image_decoder(
        new ImageDecoder(resource_provider, debugger_hooks,
                         base::Bind(&ImageDecoderCallback::SuccessCallback,
                                    base::Unretained(&image_decoder_result)),
                         base::Bind(&ImageDecoderCallback::LoadCompleteCallback,
                                    base::Unretained(&image_decoder_result))));

    image_decoder->DecodeChunk(reinterpret_cast<char*>(&image_data[0]),
                               image_data.size());
    image_decoder->Finish();
    if (image_decoder_result.image) {
      base::TimeDelta decoding_time = base::Time::Now() - start;
      total_time += decoding_time;
      total_size += image_decoder_result.image->GetEstimatedSizeInBytes();
      LOG(INFO) << "Decoding " << paths[i].BaseName().value() << " takes "
                << decoding_time.InMicroseconds() << " microseconds";
    }
  }
  if (total_time.InMicroseconds() != 0) {
    LOG(INFO) << "Average decoding speed for type \"" << extension << "\" is "
              << total_size * base::Time::kMicrosecondsPerSecond /
                     total_time.InMicroseconds()
              << " byte per seconds";
  }
}

int SandboxMain(int argc, char** argv) {
  cobalt::trace_event::ScopedTraceToFile trace_to_file(
      base::FilePath(FILE_PATH_LITERAL("image_decoder_sandbox_trace.json")));

  math::Size view_size(kViewportWidth, kViewportHeight);

  base::EventDispatcher event_dispatcher;
  // Create a system window to use as a render target.
  std::unique_ptr<SystemWindow> system_window(
      new cobalt::system_window::SystemWindow(&event_dispatcher, view_size));

  // Construct a renderer module using default options.
  RendererModule::Options renderer_module_options;
  RendererModule renderer_module(system_window.get(), renderer_module_options);

  // Try to decode all images in the given folder.
  ResourceProvider* resource_provider =
      renderer_module.pipeline()->GetResourceProvider();
  DecodeImages(resource_provider, ".jpg");
  DecodeImages(resource_provider, ".png");
  DecodeImages(resource_provider, ".webp");

  return 0;
}

}  // namespace
}  // namespace sandbox
}  // namespace image
}  // namespace loader
}  // namespace cobalt

COBALT_WRAP_SIMPLE_MAIN(cobalt::loader::image::sandbox::SandboxMain);
