// Copyright 2015 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 "remoting/test/refresh_token_store.h"

#include "base/files/file_util.h"
#include "base/files/important_file_writer.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/values.h"

namespace {
const base::FilePath::CharType kTokenFileName[] =
    FILE_PATH_LITERAL("refresh_tokens.json");
const base::FilePath::CharType kRemotingFolder[] =
    FILE_PATH_LITERAL("remoting");
const base::FilePath::CharType kRefreshTokenStoreFolder[] =
    FILE_PATH_LITERAL("token_store");
}  // namespace

namespace remoting {
namespace test {

// Provides functionality to write a refresh token to a local folder on disk and
// read it back during subsequent tool runs.
class RefreshTokenStoreOnDisk : public RefreshTokenStore {
 public:
  RefreshTokenStoreOnDisk(const std::string& user_name,
                          const base::FilePath& refresh_token_file_path);
  ~RefreshTokenStoreOnDisk() override;

  // RefreshTokenStore interface.
  std::string FetchRefreshToken() override;
  bool StoreRefreshToken(const std::string& refresh_token) override;

 private:
  // Returns the path for the file used to read from or store a refresh token
  // for the user.
  base::FilePath GetPathForRefreshTokenFile();

  // Used to access the user specific token file.
  std::string user_name_;

  // Path used to retrieve the refresh token file.
  base::FilePath refresh_token_file_path_;

  DISALLOW_COPY_AND_ASSIGN(RefreshTokenStoreOnDisk);
};

RefreshTokenStoreOnDisk::RefreshTokenStoreOnDisk(
    const std::string& user_name,
    const base::FilePath& refresh_token_path)
    : user_name_(user_name),
    refresh_token_file_path_(base::MakeAbsoluteFilePath(refresh_token_path)) {
}

RefreshTokenStoreOnDisk::~RefreshTokenStoreOnDisk() {
}

std::string RefreshTokenStoreOnDisk::FetchRefreshToken() {
  base::FilePath refresh_token_file_path(GetPathForRefreshTokenFile());
  DCHECK(!refresh_token_file_path.empty());
  VLOG(1) << "Reading token from: " << refresh_token_file_path.value();

  std::string file_contents;
  if (!base::ReadFileToString(refresh_token_file_path, &file_contents)) {
    VLOG(1) << "Couldn't read token file: " << refresh_token_file_path.value();
    return std::string();
  }

  std::unique_ptr<base::Value> token_data(
      base::JSONReader::Read(file_contents));
  base::DictionaryValue* tokens = nullptr;
  if (!token_data || !token_data->GetAsDictionary(&tokens)) {
    LOG(ERROR) << "Refresh token file contents were not valid JSON, "
               << "could not retrieve token.";
    return std::string();
  }

  std::string refresh_token;
  if (!tokens->GetStringWithoutPathExpansion(user_name_, &refresh_token)) {
    // This may not be an error as the file could exist but contain refresh
    // tokens for other users.
    VLOG(1) << "Could not find token for: " << user_name_;
    return std::string();
  }

  return refresh_token;
}

bool RefreshTokenStoreOnDisk::StoreRefreshToken(
    const std::string& refresh_token) {
  DCHECK(!refresh_token.empty());

  base::FilePath file_path(GetPathForRefreshTokenFile());
  DCHECK(!file_path.empty());
  VLOG(2) << "Storing token to: " << file_path.value();

  base::FilePath refresh_token_file_dir(file_path.DirName());
  if (!base::DirectoryExists(refresh_token_file_dir) &&
      !base::CreateDirectory(refresh_token_file_dir)) {
    LOG(ERROR) << "Failed to create directory, refresh token not stored.";
    return false;
  }

  std::string file_contents("{}");
  if (base::PathExists(file_path)) {
    if (!base::ReadFileToString(file_path, &file_contents)) {
      LOG(ERROR) << "Invalid token file: " << file_path.value();
      return false;
    }
  }

  std::unique_ptr<base::Value> token_data(
      base::JSONReader::Read(file_contents));
  base::DictionaryValue* tokens = nullptr;
  if (!token_data || !token_data->GetAsDictionary(&tokens)) {
    LOG(ERROR) << "Invalid refresh token file format, could not store token.";
    return false;
  }

  std::string json_string;
  tokens->SetStringWithoutPathExpansion(user_name_, refresh_token);
  if (!base::JSONWriter::Write(*token_data, &json_string)) {
    LOG(ERROR) << "Couldn't convert JSON data to string";
    return false;
  }

  if (!base::ImportantFileWriter::WriteFileAtomically(file_path, json_string)) {
    LOG(ERROR) << "Failed to save refresh token to the file on disk.";
    return false;
  }

  return true;
}

base::FilePath RefreshTokenStoreOnDisk::GetPathForRefreshTokenFile() {
  base::FilePath refresh_token_file_path(refresh_token_file_path_);

  // If we weren't given a specific file path, then use the default path.
  if (refresh_token_file_path.empty()) {
    if (!GetTempDir(&refresh_token_file_path)) {
      LOG(WARNING) << "Failed to retrieve temporary directory path.";
      return base::FilePath();
    }

    refresh_token_file_path = refresh_token_file_path.Append(kRemotingFolder);
    refresh_token_file_path =
        refresh_token_file_path.Append(kRefreshTokenStoreFolder);
  }

  // If no file has been specified, then we will use a default file name.
  if (refresh_token_file_path.Extension().empty()) {
    refresh_token_file_path = refresh_token_file_path.Append(kTokenFileName);
  }

  return refresh_token_file_path;
}

std::unique_ptr<RefreshTokenStore> RefreshTokenStore::OnDisk(
    const std::string& user_name,
    const base::FilePath& refresh_token_file_path) {
  return base::WrapUnique<RefreshTokenStore>(
      new RefreshTokenStoreOnDisk(user_name, refresh_token_file_path));
}

}  // namespace test
}  // namespace remoting
