/*
 * Copyright 2016 Google Inc. 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 "base/debug/trace_event.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/time.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 renderer::RendererModule;
using render_tree::ResourceProvider;
using system_window::SystemWindow;
using file_util::FileEnumerator;

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

  void FailureCallback(const std::string& failure_message) {
    LOG(WARNING) << failure_message;
  }

  void ErrorCallback(const std::string& error_message) {
    LOG(ERROR) << error_message;
  }

  scoped_refptr<render_tree::Image> image;
};

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

  std::vector<FilePath> result;
  FileEnumerator file_enumerator(image_path, false /* Not recursive */,
                                 FileEnumerator::FILES);
  for (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 FilePath& file_path) {
  int64 size;
  std::vector<uint8> data;

  bool success = file_util::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 = file_util::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<FilePath> paths = GetImagePaths(extension);
  base::TimeDelta total_time;
  size_t total_size = 0;

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

    base::Time start = base::Time::Now();
    scoped_ptr<Decoder> image_decoder(new ImageDecoder(
        resource_provider, base::Bind(&ImageDecoderCallback::SuccessCallback,
                                      base::Unretained(&image_decoder_result)),
        base::Bind(&ImageDecoderCallback::FailureCallback,
                   base::Unretained(&image_decoder_result)),
        base::Bind(&ImageDecoderCallback::ErrorCallback,
                   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(
      FilePath(FILE_PATH_LITERAL("image_decoder_sandbox_trace.json")));

  base::EventDispatcher event_dispatcher;
  // Create a system window to use as a render target.
  scoped_ptr<SystemWindow> system_window =
      cobalt::system_window::CreateSystemWindow(
          &event_dispatcher,
          cobalt::math::Size(kViewportWidth, kViewportHeight));

  // 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);
