// Copyright (c) 2012 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 "net/http/http_auth_handler.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "net/base/net_errors.h"

namespace net {

HttpAuthHandler::HttpAuthHandler()
    : auth_scheme_(HttpAuth::AUTH_SCHEME_MAX),
      score_(-1),
      target_(HttpAuth::AUTH_NONE),
      properties_(-1) {
}

HttpAuthHandler::~HttpAuthHandler() {
}

bool HttpAuthHandler::InitFromChallenge(
    HttpAuth::ChallengeTokenizer* challenge,
    HttpAuth::Target target,
    const GURL& origin,
    const BoundNetLog& net_log) {
  origin_ = origin;
  target_ = target;
  score_ = -1;
  properties_ = -1;
  net_log_ = net_log;

  auth_challenge_ = challenge->challenge_text();
  bool ok = Init(challenge);

  // Init() is expected to set the scheme, realm, score, and properties.  The
  // realm may be empty.
  DCHECK(!ok || score_ != -1);
  DCHECK(!ok || properties_ != -1);
  DCHECK(!ok || auth_scheme_ != HttpAuth::AUTH_SCHEME_MAX);

  return ok;
}

namespace {

NetLog::EventType EventTypeFromAuthTarget(HttpAuth::Target target) {
  switch (target) {
    case HttpAuth::AUTH_PROXY:
      return NetLog::TYPE_AUTH_PROXY;
    case HttpAuth::AUTH_SERVER:
      return NetLog::TYPE_AUTH_SERVER;
    default:
      NOTREACHED();
      return NetLog::TYPE_CANCELLED;
  }
}

}  // namespace

int HttpAuthHandler::GenerateAuthToken(
    const AuthCredentials* credentials, const HttpRequestInfo* request,
    const CompletionCallback& callback, std::string* auth_token) {
  // TODO(cbentzel): Enforce non-NULL callback after cleaning up SocketStream.
  DCHECK(request);
  DCHECK(credentials != NULL || AllowsDefaultCredentials());
  DCHECK(auth_token != NULL);
  DCHECK(callback_.is_null());
  callback_ = callback;
  net_log_.BeginEvent(EventTypeFromAuthTarget(target_));
  int rv = GenerateAuthTokenImpl(
      credentials, request,
      base::Bind(&HttpAuthHandler::OnGenerateAuthTokenComplete,
                 base::Unretained(this)),
      auth_token);
  if (rv != ERR_IO_PENDING)
    FinishGenerateAuthToken();
  return rv;
}

bool HttpAuthHandler::NeedsIdentity() {
  return true;
}

bool HttpAuthHandler::AllowsDefaultCredentials() {
  return false;
}

bool HttpAuthHandler::AllowsExplicitCredentials() {
  return true;
}

void HttpAuthHandler::OnGenerateAuthTokenComplete(int rv) {
  CompletionCallback callback = callback_;
  FinishGenerateAuthToken();
  if (!callback.is_null())
    callback.Run(rv);
}

void HttpAuthHandler::FinishGenerateAuthToken() {
  // TOOD(cbentzel): Should this be done in OK case only?
  net_log_.EndEvent(EventTypeFromAuthTarget(target_));
  callback_.Reset();
}

}  // namespace net
