// 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/socket_stream/socket_stream_job.h"

#include "base/memory/singleton.h"
#include "net/http/transport_security_state.h"
#include "net/socket_stream/socket_stream_job_manager.h"
#include "net/ssl/ssl_config_service.h"
#include "net/url_request/url_request_context.h"

namespace net {

// static
SocketStreamJob::ProtocolFactory* SocketStreamJob::RegisterProtocolFactory(
    const std::string& scheme, ProtocolFactory* factory) {
  return SocketStreamJobManager::GetInstance()->RegisterProtocolFactory(
      scheme, factory);
}

// static
SocketStreamJob* SocketStreamJob::CreateSocketStreamJob(
    const GURL& url,
    SocketStream::Delegate* delegate,
    TransportSecurityState* sts,
    SSLConfigService* ssl) {
  GURL socket_url(url);
  TransportSecurityState::DomainState domain_state;
  if (url.scheme() == "ws" && sts && sts->GetDomainState(
          url.host(), SSLConfigService::IsSNIAvailable(ssl), &domain_state) &&
      domain_state.ShouldUpgradeToSSL()) {
    url_canon::Replacements<char> replacements;
    static const char kNewScheme[] = "wss";
    replacements.SetScheme(kNewScheme,
                           url_parse::Component(0, strlen(kNewScheme)));
    socket_url = url.ReplaceComponents(replacements);
  }
  return SocketStreamJobManager::GetInstance()->CreateJob(socket_url, delegate);
}

SocketStreamJob::SocketStreamJob() {}

SocketStream::UserData* SocketStreamJob::GetUserData(const void* key) const {
  return socket_->GetUserData(key);
}

void SocketStreamJob::SetUserData(const void* key,
                                  SocketStream::UserData* data) {
  socket_->SetUserData(key, data);
}

void SocketStreamJob::Connect() {
  socket_->Connect();
}

bool SocketStreamJob::SendData(const char* data, int len) {
  return socket_->SendData(data, len);
}

void SocketStreamJob::Close() {
  socket_->Close();
}

void SocketStreamJob::RestartWithAuth(const AuthCredentials& credentials) {
  socket_->RestartWithAuth(credentials);
}

void SocketStreamJob::CancelWithError(int error) {
  socket_->CancelWithError(error);
}

void SocketStreamJob::CancelWithSSLError(const net::SSLInfo& ssl_info) {
  socket_->CancelWithSSLError(ssl_info);
}

void SocketStreamJob::ContinueDespiteError() {
  socket_->ContinueDespiteError();
}

void SocketStreamJob::DetachDelegate() {
  socket_->DetachDelegate();
}

SocketStreamJob::~SocketStreamJob() {}

}  // namespace net
