// 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 "components/signin/core/browser/dice_header_helper.h"

#include <vector>

#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/gaia_urls.h"

namespace signin {

const char kDiceProtocolVersion[] = "1";

namespace {

// Request parameters.
const char kRequestSigninAll[] = "all_accounts";
const char kRequestSignoutNoConfirmation[] = "no_confirmation";
const char kRequestSignoutShowConfirmation[] = "show_confirmation";

// Signin response parameters.
const char kSigninActionAttrName[] = "action";
const char kSigninAuthUserAttrName[] = "authuser";
const char kSigninAuthorizationCodeAttrName[] = "authorization_code";
const char kSigninEmailAttrName[] = "email";
const char kSigninIdAttrName[] = "id";

// Signout response parameters.
const char kSignoutEmailAttrName[] = "email";
const char kSignoutSessionIndexAttrName[] = "sessionindex";
const char kSignoutObfuscatedIDAttrName[] = "obfuscatedid";

// Determines the Dice action that has been passed from Gaia in the header.
DiceAction GetDiceActionFromHeader(const std::string& value) {
  if (value == "SIGNIN")
    return DiceAction::SIGNIN;
  else if (value == "SIGNOUT")
    return DiceAction::SIGNOUT;
  else if (value == "ENABLE_SYNC")
    return DiceAction::ENABLE_SYNC;
  else
    return DiceAction::NONE;
}

}  // namespace

DiceHeaderHelper::DiceHeaderHelper(AccountConsistencyMethod account_consistency)
    : SigninHeaderHelper("Dice"), account_consistency_(account_consistency) {}

// static
DiceResponseParams DiceHeaderHelper::BuildDiceSigninResponseParams(
    const std::string& header_value) {
  DCHECK(!header_value.empty());
  DiceResponseParams params;
  ResponseHeaderDictionary header_dictionary =
      ParseAccountConsistencyResponseHeader(header_value);
  if (header_dictionary.count(kSigninActionAttrName) != 1u)
    return params;

  DiceResponseParams::AccountInfo* info = nullptr;
  switch (GetDiceActionFromHeader(
      header_dictionary.find(kSigninActionAttrName)->second)) {
    case DiceAction::NONE:
    case DiceAction::SIGNOUT:
      DLOG(WARNING) << "Only SIGNIN and ENABLE_SYNC are supported through "
                    << "X-Chrome-ID-Consistency-Response :" << header_value;
      return params;
    case DiceAction::SIGNIN:
      params.user_intention = DiceAction::SIGNIN;
      params.signin_info = std::make_unique<DiceResponseParams::SigninInfo>();
      info = &params.signin_info->account_info;
      break;
    case DiceAction::ENABLE_SYNC:
      params.user_intention = DiceAction::ENABLE_SYNC;
      params.enable_sync_info =
          std::make_unique<DiceResponseParams::EnableSyncInfo>();
      info = &params.enable_sync_info->account_info;
      break;
  }

  ResponseHeaderDictionary::const_iterator it = header_dictionary.begin();
  for (; it != header_dictionary.end(); ++it) {
    const std::string key_name(it->first);
    const std::string value(it->second);
    if (key_name == kSigninActionAttrName) {
      // Do nothing, this was already parsed.
    } else if (key_name == kSigninIdAttrName) {
      info->gaia_id = value;
    } else if (key_name == kSigninEmailAttrName) {
      info->email = value;
    } else if (key_name == kSigninAuthUserAttrName) {
      bool parse_success = base::StringToInt(value, &info->session_index);
      if (!parse_success)
        info->session_index = -1;
    } else if (key_name == kSigninAuthorizationCodeAttrName) {
      if (params.signin_info)
        params.signin_info->authorization_code = value;
      else
        DLOG(WARNING) << "Authorization code expected only with SIGNIN action";
    } else {
      DLOG(WARNING) << "Unexpected Gaia header attribute '" << key_name << "'.";
    }
  }

  if (info->gaia_id.empty() || info->email.empty() ||
      info->session_index == -1) {
    DLOG(WARNING) << "Missing account info in Dice header: " << header_value;
    return DiceResponseParams();
  }

  if (params.signin_info && params.signin_info->authorization_code.empty()) {
    DLOG(WARNING) << "Missing authorization code in Dice SIGNIN header: "
                  << header_value;
    return DiceResponseParams();
  }

  return params;
}

// static
DiceResponseParams DiceHeaderHelper::BuildDiceSignoutResponseParams(
    const std::string& header_value) {
  // Google internal documentation of this header at:
  // http://go/gaia-response-headers
  DCHECK(!header_value.empty());
  DiceResponseParams params;
  params.user_intention = DiceAction::SIGNOUT;
  std::vector<std::string> gaia_ids;
  std::vector<std::string> emails;
  std::vector<int> session_indices;
  ResponseHeaderDictionary header_dictionary =
      ParseAccountConsistencyResponseHeader(header_value);
  ResponseHeaderDictionary::const_iterator it = header_dictionary.begin();
  for (; it != header_dictionary.end(); ++it) {
    const std::string key_name(it->first);
    const std::string value(it->second);
    if (key_name == kSignoutObfuscatedIDAttrName) {
      gaia_ids.push_back(value);
      // The Gaia ID is wrapped in quotes.
      base::TrimString(value, "\"", &gaia_ids.back());
    } else if (key_name == kSignoutEmailAttrName) {
      // The email is wrapped in quotes.
      emails.push_back(value);
      base::TrimString(value, "\"", &emails.back());
    } else if (key_name == kSignoutSessionIndexAttrName) {
      int session_index = -1;
      bool parse_success = base::StringToInt(value, &session_index);
      if (parse_success)
        session_indices.push_back(session_index);
    } else {
      DLOG(WARNING) << "Unexpected Gaia header attribute '" << key_name << "'.";
    }
  }

  if ((gaia_ids.size() != emails.size()) ||
      (gaia_ids.size() != session_indices.size())) {
    DLOG(WARNING) << "Invalid parameter count for Dice SIGNOUT header: "
                  << header_value;
    return DiceResponseParams();
  }

  if (gaia_ids.empty()) {
    DLOG(WARNING) << "No account specified in Dice SIGNOUT header";
    return DiceResponseParams();
  }

  params.signout_info = std::make_unique<DiceResponseParams::SignoutInfo>();
  for (size_t i = 0; i < gaia_ids.size(); ++i) {
    params.signout_info->account_infos.emplace_back(gaia_ids[i], emails[i],
                                                    session_indices[i]);
  }

  return params;
}

bool DiceHeaderHelper::ShouldBuildRequestHeader(
    const GURL& url,
    const content_settings::CookieSettings* cookie_settings) {
  return IsUrlEligibleForRequestHeader(url);
}

bool DiceHeaderHelper::IsUrlEligibleForRequestHeader(const GURL& url) {
  if (account_consistency_ == AccountConsistencyMethod::kDisabled ||
      account_consistency_ == AccountConsistencyMethod::kMirror) {
    return false;
  }

  return gaia::IsGaiaSignonRealm(url.GetOrigin());
}

std::string DiceHeaderHelper::BuildRequestHeader(
    const std::string& sync_account_id,
    const std::string& device_id) {
  std::vector<std::string> parts;
  parts.push_back(base::StringPrintf("version=%s", kDiceProtocolVersion));
  parts.push_back("client_id=" +
                  GaiaUrls::GetInstance()->oauth2_chrome_client_id());
  if (!device_id.empty())
    parts.push_back("device_id=" + device_id);
  if (!sync_account_id.empty())
    parts.push_back("sync_account_id=" + sync_account_id);

  // Restrict Signin to Sync account only when fixing auth errors.
  std::string signin_mode = kRequestSigninAll;
  parts.push_back("signin_mode=" + signin_mode);

  // Show the signout confirmation only when Dice is fully enabled.
  const char* signout_mode_value =
      (account_consistency_ == AccountConsistencyMethod::kDice)
          ? kRequestSignoutShowConfirmation
          : kRequestSignoutNoConfirmation;
  parts.push_back(base::StringPrintf("signout_mode=%s", signout_mode_value));

  return base::JoinString(parts, ",");
}

}  // namespace signin
