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

#include "ash/ambient/ambient_photo_cache.h"

#include <fstream>
#include <iostream>

#include "ash/ambient/ambient_access_token_controller.h"
#include "ash/ambient/ambient_constants.h"
#include "ash/ambient/ambient_photo_cache_settings.h"
#include "ash/constants/ash_features.h"
#include "ash/public/cpp/ambient/ambient_client.h"
#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ref.h"
#include "base/memory/weak_ptr.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/system/sys_info.h"
#include "base/task/sequenced_task_runner.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/mojom/url_response_head.mojom.h"

namespace ash {

namespace {

constexpr net::NetworkTrafficAnnotationTag kAmbientPhotoCacheNetworkTag =
    net::DefineNetworkTrafficAnnotation("ambient_photo_cache", R"(
        semantics {
          sender: "Ambient photo"
          description:
            "Get ambient photo from url to store limited number of photos in "
            "the device cache. This is used to show the screensaver when the "
            "user is idle. The url can be Backdrop service to provide pictures"
            " from internal gallery, weather/time photos served by Google, or "
            "user selected album from Google photos."
          trigger:
            "Triggered by a photo refresh timer, after the device has been "
            "idle and the battery is charging."
          data: "None."
          destination: GOOGLE_OWNED_SERVICE
        }
        policy {
         cookies_allowed: NO
         setting:
           "This feature is off by default and can be overridden by users."
         policy_exception_justification:
           "This feature is set by user settings.ambient_mode.enabled pref. "
           "The user setting is per device and cannot be overriden by admin."
        })");

// Helper function to extract response code from |SimpleURLLoader|.
int GetResponseCode(network::SimpleURLLoader* simple_loader) {
  if (simple_loader->ResponseInfo() && simple_loader->ResponseInfo()->headers)
    return simple_loader->ResponseInfo()->headers->response_code();
  else
    return -1;
}

std::unique_ptr<network::SimpleURLLoader> CreateSimpleURLLoader(
    const std::string& url,
    const std::string& token) {
  auto resource_request = std::make_unique<network::ResourceRequest>();
  resource_request->url = GURL(url);
  resource_request->method = "GET";
  resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;

  if (token.empty())
    DVLOG(2) << "Failed to fetch access token";
  else
    resource_request->headers.SetHeader("Authorization", "Bearer " + token);

  return network::SimpleURLLoader::Create(std::move(resource_request),
                                          kAmbientPhotoCacheNetworkTag);
}

bool CreateDirIfNotExists(const base::FilePath& path) {
  return base::DirectoryExists(path) || base::CreateDirectory(path);
}

bool WriteOrDeleteFile(const base::FilePath& path,
                       const ambient::PhotoCacheEntry& cache_entry) {
  // If the primary photo is empty, the same as the related photo.
  if (!cache_entry.has_primary_photo() ||
      cache_entry.primary_photo().image().empty()) {
    base::DeleteFile(path);
    return false;
  }

  if (!CreateDirIfNotExists(path.DirName())) {
    LOG(ERROR) << "Cannot create ambient mode directory.";
    return false;
  }

  if (base::SysInfo::AmountOfFreeDiskSpace(path.DirName()) <
      kMaxReservedAvailableDiskSpaceByte) {
    LOG(ERROR) << "Not enough disk space left.";
    return false;
  }

  // Create a temp file.
  base::FilePath temp_file;
  if (!base::CreateTemporaryFileInDir(path.DirName(), &temp_file)) {
    LOG(ERROR) << "Cannot create a temporary file.";
    return false;
  }

  // Write to the tmp file.
  const char* path_str = temp_file.value().c_str();
  std::fstream output(path_str,
                      std::ios::out | std::ios::trunc | std::ios::binary);
  if (!cache_entry.SerializeToOstream(&output)) {
    LOG(ERROR) << "Cannot write the temporary file.";
    base::DeleteFile(temp_file);
    return false;
  }

  // Replace the current file with the temp file.
  if (!base::ReplaceFile(temp_file, path, /*error=*/nullptr)) {
    LOG(ERROR) << "Cannot replace the temporary file.";
    base::DeleteFile(temp_file);
    base::DeleteFile(path);
    return false;
  }

  return true;
}

const base::FilePath& GetCacheRootDir(ambient_photo_cache::Store store) {
  switch (store) {
    case ambient_photo_cache::Store::kPrimary:
      return GetAmbientPhotoCacheRootDir();
    case ambient_photo_cache::Store::kBackup:
      return GetAmbientBackupPhotoCacheRootDir();
  }
  NOTREACHED_NORETURN() << "Unknown cache store: " << static_cast<int>(store);
}

base::FilePath GetCachePath(int cache_index, const base::FilePath& root_path) {
  return root_path.Append(base::NumberToString(cache_index) + kPhotoCacheExt);
}

scoped_refptr<base::SequencedTaskRunner>& GetFileTaskRunner() {
  static base::NoDestructor<scoped_refptr<base::SequencedTaskRunner>>
      kFileTaskRunner;
  return *kFileTaskRunner;
}

void OnUrlDownloaded(
    base::OnceCallback<void(std::string&&)> callback,
    std::unique_ptr<network::SimpleURLLoader> simple_loader,
    scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
    std::unique_ptr<std::string> response_body) {
  if (simple_loader->NetError() == net::OK && response_body) {
    std::move(callback).Run(std::move(*response_body));
    return;
  }

  LOG(ERROR) << "Downloading to string failed with error code: "
             << GetResponseCode(simple_loader.get()) << " with network error "
             << simple_loader->NetError();
  std::move(callback).Run(std::string());
}

void OnUrlDownloadedToTempFile(
    base::OnceCallback<void(base::FilePath)> callback,
    std::unique_ptr<network::SimpleURLLoader> simple_loader,
    scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
    base::FilePath temp_path) {
  CHECK(callback);
  if (simple_loader->NetError() != net::OK || temp_path.empty()) {
    LOG(ERROR) << "Downloading to file failed with error code: "
               << GetResponseCode(simple_loader.get()) << " with network error "
               << simple_loader->NetError();

    if (!temp_path.empty()) {
      // Clean up temporary file.
      GetFileTaskRunner()->PostTask(
          FROM_HERE,
          base::BindOnce(
              [](const base::FilePath& path) { base::DeleteFile(path); },
              temp_path));
    }
    std::move(callback).Run(base::FilePath());
    return;
  }
  std::move(callback).Run(std::move(temp_path));
}

void DownloadPhotoInternal(
    const std::string& url,
    scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
    base::OnceCallback<void(std::string&&)> callback,
    const std::string& gaia_id,
    const std::string& access_token) {
  std::unique_ptr<network::SimpleURLLoader> simple_loader =
      CreateSimpleURLLoader(url, access_token);
  auto* loader_ptr = simple_loader.get();
  auto* loader_factory_ptr = loader_factory.get();

  loader_ptr->DownloadToString(
      loader_factory_ptr,
      base::BindOnce(&OnUrlDownloaded, std::move(callback),
                     std::move(simple_loader), std::move(loader_factory)),
      kMaxImageSizeInBytes);
}

void DownloadPhotoToTempFileInternal(
    const std::string& url,
    scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
    base::OnceCallback<void(base::FilePath)> callback,
    const std::string& gaia_id,
    const std::string& access_token) {
  std::unique_ptr<network::SimpleURLLoader> simple_loader =
      CreateSimpleURLLoader(url, access_token);
  auto* loader_ptr = simple_loader.get();
  auto* loader_factory_ptr = loader_factory.get();
  loader_ptr->DownloadToTempFile(
      loader_factory_ptr,
      base::BindOnce(&OnUrlDownloadedToTempFile, std::move(callback),
                     std::move(simple_loader), std::move(loader_factory)));
}

}  // namespace

namespace ambient_photo_cache {

void SetFileTaskRunner(scoped_refptr<base::SequencedTaskRunner> task_runner) {
  GetFileTaskRunner() = std::move(task_runner);
}

void DownloadPhoto(const std::string& url,
                   AmbientAccessTokenController& access_token_controller,
                   base::OnceCallback<void(std::string&&)> callback) {
  access_token_controller.RequestAccessToken(base::BindOnce(
      &DownloadPhotoInternal, url, AmbientClient::Get()->GetURLLoaderFactory(),
      std::move(callback)));
}

void DownloadPhotoToTempFile(
    const std::string& url,
    AmbientAccessTokenController& access_token_controller,
    base::OnceCallback<void(base::FilePath)> callback) {
  access_token_controller.RequestAccessToken(base::BindOnce(
      &DownloadPhotoToTempFileInternal, url,
      AmbientClient::Get()->GetURLLoaderFactory(), std::move(callback)));
}

void WritePhotoCache(Store store,
                     int cache_index,
                     const ambient::PhotoCacheEntry& cache_entry,
                     base::OnceClosure callback) {
  DCHECK_LT(cache_index, kMaxNumberOfCachedImages);
  GetFileTaskRunner()->PostTaskAndReply(
      FROM_HERE,
      base::BindOnce(
          [](int cache_index, const base::FilePath& root_path,
             const ambient::PhotoCacheEntry& cache_entry) {
            auto cache_path = GetCachePath(cache_index, root_path);
            WriteOrDeleteFile(cache_path, cache_entry);
          },
          cache_index, GetCacheRootDir(store), cache_entry),
      std::move(callback));
}

void ReadPhotoCache(
    Store store,
    int cache_index,
    base::OnceCallback<void(::ambient::PhotoCacheEntry)> callback) {
  GetFileTaskRunner()->PostTaskAndReplyWithResult(
      FROM_HERE,
      base::BindOnce(
          [](int cache_index, const base::FilePath& root_path) {
            auto cache_path = GetCachePath(cache_index, root_path);

            // Read the existing cache.
            const char* path_str = cache_path.value().c_str();
            std::fstream input(path_str, std::ios::in | std::ios::binary);
            ambient::PhotoCacheEntry cache_entry;
            if (!input || !cache_entry.ParseFromIstream(&input)) {
              LOG(ERROR) << "Unable to read photo cache";
              cache_entry = ::ambient::PhotoCacheEntry();
              base::DeleteFile(cache_path);
            }
            return cache_entry;
          },
          cache_index, GetCacheRootDir(store)),
      std::move(callback));
}

void Clear(Store store) {
  GetFileTaskRunner()->PostTask(FROM_HERE,
                                base::BindOnce(
                                    [](const base::FilePath& file_path) {
                                      base::DeletePathRecursively(file_path);
                                    },
                                    GetCacheRootDir(store)));
}

}  // namespace ambient_photo_cache
}  // namespace ash
