// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/vr/assets_loader.h"

#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/memory/singleton.h"
#include "base/single_thread_task_runner.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "chrome/browser/vr/metrics/metrics_helper.h"
#include "chrome/browser/vr/model/assets.h"
#include "chrome/browser/vr/vr_buildflags.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "media/audio/sounds/wav_audio_handler.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/codec/png_codec.h"

namespace vr {

namespace {

constexpr char kMinVersionWithGradients[] = "1.1";
constexpr char kMinVersionWithSounds[] = "2.0";
constexpr char kMinVersionWithInactiveButtonClickSound[] = "2.2";

static const base::FilePath::CharType kBackgroundBaseFilename[] =
    FILE_PATH_LITERAL("background");
static const base::FilePath::CharType kNormalGradientBaseFilename[] =
    FILE_PATH_LITERAL("normal_gradient");
static const base::FilePath::CharType kIncognitoGradientBaseFilename[] =
    FILE_PATH_LITERAL("incognito_gradient");
static const base::FilePath::CharType kFullscreenGradientBaseFilename[] =
    FILE_PATH_LITERAL("fullscreen_gradient");
static const base::FilePath::CharType kPngExtension[] =
    FILE_PATH_LITERAL("png");
static const base::FilePath::CharType kJpegExtension[] =
    FILE_PATH_LITERAL("jpeg");

static const base::FilePath::CharType kButtonHoverSoundFilename[] =
    FILE_PATH_LITERAL("button_hover.wav");
static const base::FilePath::CharType kButtonClickSoundFilename[] =
    FILE_PATH_LITERAL("button_click.wav");
static const base::FilePath::CharType kBackButtonClickSoundFilename[] =
    FILE_PATH_LITERAL("back_button_click.wav");
static const base::FilePath::CharType kInactiveButtonClickSoundFilename[] =
    FILE_PATH_LITERAL("inactive_button_click.wav");

}  // namespace

struct AssetsLoaderSingletonTrait
    : public base::DefaultSingletonTraits<AssetsLoader> {
  static AssetsLoader* New() { return new AssetsLoader(); }
  static void Delete(AssetsLoader* assets) { delete assets; }
};

// static
AssetsLoader* AssetsLoader::GetInstance() {
  return base::Singleton<AssetsLoader, AssetsLoaderSingletonTrait>::get();
}

// static
base::Version AssetsLoader::MinVersionWithGradients() {
  return base::Version(kMinVersionWithGradients);
}

// static
bool AssetsLoader::AssetsSupported() {
#if BUILDFLAG(USE_VR_ASSETS_COMPONENT)
  return true;
#else   // BUILDFLAG(USE_VR_ASSETS_COMPONENT)
  return false;
#endif  // BUILDFLAG(USE_VR_ASSETS_COMPONENT)
}

void AssetsLoader::OnComponentReady(
    const base::Version& version,
    const base::FilePath& install_dir,
    std::unique_ptr<base::DictionaryValue> manifest) {
  main_thread_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&AssetsLoader::OnComponentReadyInternal,
                     weak_ptr_factory_.GetWeakPtr(), version, install_dir));
}

void AssetsLoader::Load(OnAssetsLoadedCallback on_loaded) {
  main_thread_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&AssetsLoader::LoadInternal,
                                weak_ptr_factory_.GetWeakPtr(),
                                base::ThreadTaskRunnerHandle::Get(),
                                std::move(on_loaded)));
}

MetricsHelper* AssetsLoader::GetMetricsHelper() {
  // If we instantiate metrics_helper_ in the constructor all functions of
  // MetricsHelper must be called in a valid sequence from the thread the
  // constructor ran on. However, the assets class can be instantiated from any
  // thread. To avoid the aforementioned restriction, create metrics_helper_ the
  // first time it is used and, thus, give the caller control over when the
  // sequence starts.
  if (!metrics_helper_) {
    metrics_helper_ = std::make_unique<MetricsHelper>();
  }
  return metrics_helper_.get();
}

bool AssetsLoader::ComponentReady() {
  DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
  return component_ready_;
}

void AssetsLoader::SetOnComponentReadyCallback(
    const base::RepeatingCallback<void()>& on_component_ready) {
  DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
  on_component_ready_callback_ = on_component_ready;
}

AssetsLoadStatus LoadImage(const base::FilePath& component_install_dir,
                           const base::FilePath::CharType* base_file,
                           std::unique_ptr<SkBitmap>* out_image) {
  bool is_png = false;
  std::string encoded_file_content;

  base::FilePath file_path = component_install_dir.Append(base_file);

  if (base::PathExists(file_path.AddExtension(kPngExtension))) {
    file_path = file_path.AddExtension(kPngExtension);
    is_png = true;
  } else if (base::PathExists(file_path.AddExtension(kJpegExtension))) {
    file_path = file_path.AddExtension(kJpegExtension);
  } else {
    return AssetsLoadStatus::kNotFound;
  }

  if (!base::ReadFileToString(file_path, &encoded_file_content)) {
    return AssetsLoadStatus::kParseFailure;
  }

  if (is_png) {
    (*out_image) = std::make_unique<SkBitmap>();
    if (!gfx::PNGCodec::Decode(
            reinterpret_cast<const unsigned char*>(encoded_file_content.data()),
            encoded_file_content.size(), out_image->get())) {
      out_image->reset();
    }
  } else {
    (*out_image) = gfx::JPEGCodec::Decode(
        reinterpret_cast<const unsigned char*>(encoded_file_content.data()),
        encoded_file_content.size());
  }

  if (!out_image->get()) {
    return AssetsLoadStatus::kInvalidContent;
  }

  return AssetsLoadStatus::kSuccess;
}

AssetsLoadStatus LoadSound(const base::FilePath& component_install_dir,
                           const base::FilePath::CharType* file_name,
                           std::unique_ptr<std::string>* out_buffer) {
  base::FilePath file_path = component_install_dir.Append(file_name);
  if (!base::PathExists(file_path)) {
    return AssetsLoadStatus::kNotFound;
  }

  auto buffer = std::make_unique<std::string>();
  if (!base::ReadFileToString(file_path, buffer.get())) {
    return AssetsLoadStatus::kParseFailure;
  }

  if (!media::WavAudioHandler::Create(*buffer)) {
    return AssetsLoadStatus::kInvalidContent;
  }

  *out_buffer = std::move(buffer);
  return AssetsLoadStatus::kSuccess;
}

// static
void AssetsLoader::LoadAssetsTask(
    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
    const base::Version& component_version,
    const base::FilePath& component_install_dir,
    OnAssetsLoadedCallback on_loaded) {
  auto assets = std::make_unique<Assets>();
  AssetsLoadStatus status = AssetsLoadStatus::kSuccess;

  status = LoadImage(component_install_dir, kBackgroundBaseFilename,
                     &assets->background);

  if (component_version >= AssetsLoader::MinVersionWithGradients()) {
    if (status == AssetsLoadStatus::kSuccess) {
      status = LoadImage(component_install_dir, kNormalGradientBaseFilename,
                         &assets->normal_gradient);
    }
    if (status == AssetsLoadStatus::kSuccess) {
      status = LoadImage(component_install_dir, kIncognitoGradientBaseFilename,
                         &assets->incognito_gradient);
    }
    if (status == AssetsLoadStatus::kSuccess) {
      status = LoadImage(component_install_dir, kFullscreenGradientBaseFilename,
                         &assets->fullscreen_gradient);
    }
  }

  std::vector<std::tuple<const char*, const base::FilePath::CharType*,
                         std::unique_ptr<std::string>*>>
      sounds = {{kMinVersionWithSounds, kButtonHoverSoundFilename,
                 &assets->button_hover_sound},
                {kMinVersionWithSounds, kButtonClickSoundFilename,
                 &assets->button_click_sound},
                {kMinVersionWithSounds, kBackButtonClickSoundFilename,
                 &assets->back_button_click_sound},
                {kMinVersionWithInactiveButtonClickSound,
                 kInactiveButtonClickSoundFilename,
                 &assets->inactive_button_click_sound}};

  auto sounds_iter = sounds.begin();
  while (status == AssetsLoadStatus::kSuccess && sounds_iter != sounds.end()) {
    const char* min_version;
    const base::FilePath::CharType* file_name;
    std::unique_ptr<std::string>* data;
    std::tie(min_version, file_name, data) = *sounds_iter;
    if (component_version >= base::Version(min_version)) {
      status = LoadSound(component_install_dir, file_name, data);
    }
    sounds_iter++;
  }

  if (status != AssetsLoadStatus::kSuccess) {
    assets.reset();
  }

  task_runner->PostTask(
      FROM_HERE, base::BindOnce(std::move(on_loaded), status, std::move(assets),
                                component_version));
}

AssetsLoader::AssetsLoader()
    : main_thread_task_runner_(base::CreateSingleThreadTaskRunnerWithTraits(
          {content::BrowserThread::UI})),
      weak_ptr_factory_(this) {
  DCHECK(main_thread_task_runner_.get());
}

AssetsLoader::~AssetsLoader() = default;

void AssetsLoader::OnComponentReadyInternal(const base::Version& version,
                                            const base::FilePath& install_dir) {
  DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
  component_version_ = version;
  component_install_dir_ = install_dir;
  component_ready_ = true;
  if (on_component_ready_callback_) {
    on_component_ready_callback_.Run();
  }
  GetMetricsHelper()->OnComponentReady(version);
}

void AssetsLoader::LoadInternal(
    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
    OnAssetsLoadedCallback on_loaded) {
  DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
  DCHECK(component_ready_);
  base::PostTaskWithTraits(
      FROM_HERE, {base::TaskPriority::BEST_EFFORT, base::MayBlock()},
      base::BindOnce(&AssetsLoader::LoadAssetsTask, task_runner,
                     component_version_, component_install_dir_,
                     std::move(on_loaded)));
}

}  // namespace vr
