// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/h5vcc/h5vcc_account_manager.h"

#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "cobalt/browser/switches.h"
#include "starboard/user.h"

namespace cobalt {
namespace h5vcc {

H5vccAccountManager::H5vccAccountManager()
    : user_authorizer_(account::UserAuthorizer::Create()),
      owning_message_loop_(MessageLoop::current()), thread_("AccountManager") {
  thread_.Start();
}

void H5vccAccountManager::GetAuthToken(
    const AccessTokenCallbackHolder& callback) {
  DLOG(INFO) << "Get authorization token.";
  PostOperation(kGetToken, callback);
}

void H5vccAccountManager::RequestPairing(
    const AccessTokenCallbackHolder& callback) {
  DLOG(INFO) << "Request application linking.";
  PostOperation(kPairing, callback);
}

void H5vccAccountManager::RequestUnpairing(
    const AccessTokenCallbackHolder& callback) {
  DLOG(INFO) << "Request application unlinking.";
  PostOperation(kUnpairing, callback);
}

void H5vccAccountManager::PostOperation(
    OperationType operation_type, const AccessTokenCallbackHolder& callback) {
  DCHECK(thread_checker_.CalledOnValidThread());
  AccessTokenCallbackReference* token_callback =
      new AccessTokenCallbackHolder::Reference(this, callback);
  pending_callbacks_.push_back(token_callback);
  thread_.message_loop()->PostTask(
      FROM_HERE, base::Bind(&H5vccAccountManager::RequestOperationInternal,
                            user_authorizer_.get(), operation_type,
                            base::Bind(&H5vccAccountManager::PostResult,
                                       owning_message_loop_,
                                       base::AsWeakPtr(this),
                                       token_callback)));
}

H5vccAccountManager::~H5vccAccountManager() {
  DCHECK(thread_checker_.CalledOnValidThread());
  // Give the UserAuthorizer a chance to abort any long running pending requests
  // before the message loop gets shut down.
  user_authorizer_->Shutdown();
}

// static
void H5vccAccountManager::RequestOperationInternal(
    account::UserAuthorizer* user_authorizer, OperationType operation,
    const base::Callback<void(const std::string&, uint64_t)>& post_result) {
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(browser::switches::kDisableSignIn)) {
    post_result.Run(std::string(), 0);
    return;
  }
#endif  // defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)

  SbUser current_user = SbUserGetCurrent();
  DCHECK(SbUserIsValid(current_user));

  scoped_ptr<account::AccessToken> access_token(NULL);

  switch (operation) {
    case kPairing:
      access_token = user_authorizer->AuthorizeUser(current_user);
      DLOG_IF(INFO, !access_token) << "User authorization request failed.";
      break;
    case kUnpairing:
      if (user_authorizer->DeauthorizeUser(current_user)) {
        break;
      }
      // The user canceled the flow, or there was some error. Fall into the next
      // case to get an access token if available and return that.
      DLOG(INFO) << "User deauthorization request failed. Try to get token.";
    case kGetToken:
      access_token = user_authorizer->RefreshAuthorization(current_user);
      DLOG_IF(INFO, !access_token) << "Authorization refresh request failed.";
      break;
  }

  std::string token_value;
  uint64_t expiration_in_seconds = 0;
  if (access_token) {
    token_value = access_token->token_value;
    if (access_token->expiry) {
      base::TimeDelta expires_in =
          access_token->expiry.value() - base::Time::Now();
      // If this token's expiry is in the past, then it's not a valid token.
      base::TimeDelta zero;
      if (expires_in < zero) {
        DLOG(WARNING) << "User authorization expires in the past.";
        token_value.clear();
      } else {
        expiration_in_seconds = expires_in.InSeconds();
      }
    }
  }

  post_result.Run(token_value, expiration_in_seconds);
}

// static
void H5vccAccountManager::PostResult(
    MessageLoop* message_loop,
    base::WeakPtr<H5vccAccountManager> h5vcc_account_manager,
    AccessTokenCallbackReference* token_callback,
    const std::string& token, uint64_t expiration_in_seconds) {
  message_loop->PostTask(
      FROM_HERE,
      base::Bind(&H5vccAccountManager::SendResult, h5vcc_account_manager,
                 token_callback, token, expiration_in_seconds));
}

void H5vccAccountManager::SendResult(
    AccessTokenCallbackReference* token_callback,
    const std::string& token, uint64_t expiration_in_seconds) {
  DCHECK(thread_checker_.CalledOnValidThread());
  ScopedVector<AccessTokenCallbackReference>::iterator found = std::find(
      pending_callbacks_.begin(), pending_callbacks_.end(), token_callback);
  if (found == pending_callbacks_.end()) {
    DLOG(ERROR) << "Account manager callback not valid.";
    return;
  }
  // In case a new account manager request is made as part of the callback,
  // erase the callback in the pending vector before running it, but we can't
  // delete it until after we've made the callback.
  pending_callbacks_.weak_erase(found);
  token_callback->value().Run(token, expiration_in_seconds);
  delete token_callback;
}

}  // namespace h5vcc
}  // namespace cobalt
