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

  scoped_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;
    }
  }

  scoped_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;
}

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

}  // namespace test
}  // namespace remoting
