// Copyright 2014 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 "components/search_provider_logos/logo_cache.h"

#include "base/file_util.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"

namespace {

// The cached logo metadata is persisted as JSON using these keys.
const char kSourceUrlKey[] = "url";
const char kExpirationTimeKey[] = "expiration_time";
const char kCanShowAfterExpirationKey[] = "can_show_after_expiration";
const char kFingerprintKey[] = "fingerprint";
const char kOnClickURLKey[] = "on_click_url";
const char kAltTextKey[] = "alt_text";
const char kMimeTypeKey[] = "mime_type";
const char kNumBytesKey[] = "num_bytes";

bool GetTimeValue(const base::DictionaryValue& dict,
                  const std::string& key,
                  base::Time* time) {
  std::string str;
  int64 internal_time_value;
  if (dict.GetString(key, &str) &&
      base::StringToInt64(str, &internal_time_value)) {
    *time = base::Time::FromInternalValue(internal_time_value);
    return true;
  }
  return false;
}

void SetTimeValue(base::DictionaryValue& dict,
                  const std::string& key,
                  const base::Time& time) {
  int64 internal_time_value = time.ToInternalValue();
  dict.SetString(key, base::Int64ToString(internal_time_value));
}

}  // namespace

namespace search_provider_logos {

LogoCache::LogoCache(const base::FilePath& cache_directory)
    : cache_directory_(cache_directory),
      metadata_is_valid_(false) {
  // The LogoCache can be constructed on any thread, as long as it's used
  // on a single thread after construction.
  thread_checker_.DetachFromThread();
}

LogoCache::~LogoCache() {
  DCHECK(thread_checker_.CalledOnValidThread());
}

void LogoCache::UpdateCachedLogoMetadata(const LogoMetadata& metadata) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(metadata_);
  DCHECK_EQ(metadata_->fingerprint, metadata.fingerprint);

  UpdateMetadata(make_scoped_ptr(new LogoMetadata(metadata)));
  WriteMetadata();
}

const LogoMetadata* LogoCache::GetCachedLogoMetadata() {
  DCHECK(thread_checker_.CalledOnValidThread());
  ReadMetadataIfNeeded();
  return metadata_.get();
}

void LogoCache::SetCachedLogo(const EncodedLogo* logo) {
  DCHECK(thread_checker_.CalledOnValidThread());
  scoped_ptr<LogoMetadata> metadata;
  if (logo) {
    metadata.reset(new LogoMetadata(logo->metadata));
    logo_num_bytes_ = static_cast<int>(logo->encoded_image->size());
  }
  UpdateMetadata(metadata.Pass());
  WriteLogo(logo ? logo->encoded_image : NULL);
}

scoped_ptr<EncodedLogo> LogoCache::GetCachedLogo() {
  DCHECK(thread_checker_.CalledOnValidThread());

  ReadMetadataIfNeeded();
  if (!metadata_)
    return scoped_ptr<EncodedLogo>();

  scoped_refptr<base::RefCountedString> encoded_image =
      new base::RefCountedString();
  if (!base::ReadFileToString(GetLogoPath(), &encoded_image->data())) {
    UpdateMetadata(scoped_ptr<LogoMetadata>());
    return scoped_ptr<EncodedLogo>();
  }

  if (encoded_image->size() != static_cast<size_t>(logo_num_bytes_)) {
    // Delete corrupt metadata and logo.
    DeleteLogoAndMetadata();
    UpdateMetadata(scoped_ptr<LogoMetadata>());
    return scoped_ptr<EncodedLogo>();
  }

  scoped_ptr<EncodedLogo> logo(new EncodedLogo());
  logo->encoded_image = encoded_image;
  logo->metadata = *metadata_;
  return logo.Pass();
}

// static
scoped_ptr<LogoMetadata> LogoCache::LogoMetadataFromString(
    const std::string& str, int* logo_num_bytes) {
  scoped_ptr<base::Value> value(base::JSONReader::Read(str));
  base::DictionaryValue* dict;
  if (!value || !value->GetAsDictionary(&dict))
    return scoped_ptr<LogoMetadata>();

  scoped_ptr<LogoMetadata> metadata(new LogoMetadata());
  if (!dict->GetString(kSourceUrlKey, &metadata->source_url) ||
      !dict->GetString(kFingerprintKey, &metadata->fingerprint) ||
      !dict->GetString(kOnClickURLKey, &metadata->on_click_url) ||
      !dict->GetString(kAltTextKey, &metadata->alt_text) ||
      !dict->GetString(kMimeTypeKey, &metadata->mime_type) ||
      !dict->GetBoolean(kCanShowAfterExpirationKey,
                        &metadata->can_show_after_expiration) ||
      !dict->GetInteger(kNumBytesKey, logo_num_bytes) ||
      !GetTimeValue(*dict, kExpirationTimeKey, &metadata->expiration_time)) {
    return scoped_ptr<LogoMetadata>();
  }

  return metadata.Pass();
}

// static
void LogoCache::LogoMetadataToString(const LogoMetadata& metadata,
                                     int num_bytes,
                                     std::string* str) {
  base::DictionaryValue dict;
  dict.SetString(kSourceUrlKey, metadata.source_url);
  dict.SetString(kFingerprintKey, metadata.fingerprint);
  dict.SetString(kOnClickURLKey, metadata.on_click_url);
  dict.SetString(kAltTextKey, metadata.alt_text);
  dict.SetString(kMimeTypeKey, metadata.mime_type);
  dict.SetBoolean(kCanShowAfterExpirationKey,
                  metadata.can_show_after_expiration);
  dict.SetInteger(kNumBytesKey, num_bytes);
  SetTimeValue(dict, kExpirationTimeKey, metadata.expiration_time);
  base::JSONWriter::Write(&dict, str);
}

base::FilePath LogoCache::GetLogoPath() {
  return cache_directory_.Append(FILE_PATH_LITERAL("logo"));
}

base::FilePath LogoCache::GetMetadataPath() {
  return cache_directory_.Append(FILE_PATH_LITERAL("metadata"));
}

void LogoCache::UpdateMetadata(scoped_ptr<LogoMetadata> metadata) {
  metadata_ = metadata.Pass();
  metadata_is_valid_ = true;
}

void LogoCache::ReadMetadataIfNeeded() {
  if (metadata_is_valid_)
    return;

  scoped_ptr<LogoMetadata> metadata;
  base::FilePath metadata_path = GetMetadataPath();
  std::string str;
  if (base::ReadFileToString(metadata_path, &str)) {
    metadata = LogoMetadataFromString(str, &logo_num_bytes_);
    if (!metadata) {
      // Delete corrupt metadata and logo.
      DeleteLogoAndMetadata();
    }
  }

  UpdateMetadata(metadata.Pass());
}

void LogoCache::WriteMetadata() {
  if (!EnsureCacheDirectoryExists())
    return;

  std::string str;
  LogoMetadataToString(*metadata_, logo_num_bytes_, &str);
  base::WriteFile(GetMetadataPath(), str.data(), static_cast<int>(str.size()));
}

void LogoCache::WriteLogo(scoped_refptr<base::RefCountedMemory> encoded_image) {
  if (!EnsureCacheDirectoryExists())
    return;

  if (!metadata_ || !encoded_image) {
    DeleteLogoAndMetadata();
    return;
  }

  // To minimize the chances of ending up in an undetectably broken state:
  // First, delete the metadata file, then update the logo file, then update the
  // metadata file.
  base::FilePath logo_path = GetLogoPath();
  base::FilePath metadata_path = GetMetadataPath();

  if (!base::DeleteFile(metadata_path, false))
    return;

  if (base::WriteFile(
          logo_path,
          encoded_image->front_as<char>(),
          static_cast<int>(encoded_image->size())) == -1) {
    base::DeleteFile(logo_path, false);
    return;
  }

  WriteMetadata();
}

void LogoCache::DeleteLogoAndMetadata() {
  base::DeleteFile(GetLogoPath(), false);
  base::DeleteFile(GetMetadataPath(), false);
}

bool LogoCache::EnsureCacheDirectoryExists() {
  if (base::DirectoryExists(cache_directory_))
    return true;
  return base::CreateDirectory(cache_directory_);
}

}  // namespace search_provider_logos
