// 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 "mojo/services/network/http_server_impl.h"

#include "base/logging.h"
#include "mojo/services/network/http_connection_impl.h"
#include "mojo/services/network/net_adapters.h"
#include "mojo/services/network/net_address_type_converters.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/log/net_log.h"
#include "net/socket/tcp_server_socket.h"

namespace mojo {

namespace {

const int kBackLog = 10;

}  // namespace

// static
void HttpServerImpl::Create(
    NetAddressPtr local_address,
    HttpServerDelegatePtr delegate,
    const Callback<void(NetworkErrorPtr, NetAddressPtr)>& callback) {
  HttpServerImpl* http_server = new HttpServerImpl(delegate.Pass());

  int net_error = http_server->Start(local_address.Pass());
  if (net_error != net::OK) {
    callback.Run(MakeNetworkError(net_error), nullptr);
    delete http_server;
    return;
  }
  callback.Run(MakeNetworkError(net::OK), http_server->GetLocalAddress());
}

HttpServerImpl::HttpServerImpl(HttpServerDelegatePtr delegate)
    : delegate_(delegate.Pass()) {
  DCHECK(delegate_);
  delegate_.set_error_handler(this);
}

HttpServerImpl::~HttpServerImpl() {}

int HttpServerImpl::Start(NetAddressPtr local_address) {
  DCHECK(local_address);

  scoped_ptr<net::ServerSocket> socket(
      new net::TCPServerSocket(nullptr, net::NetLog::Source()));
  int net_result = socket->Listen(local_address.To<net::IPEndPoint>(),
                                  kBackLog);
  if (net_result != net::OK)
    return net_result;

  server_.reset(new net::HttpServer(socket.Pass(), this));

  return net::OK;
}

NetAddressPtr HttpServerImpl::GetLocalAddress() const {
  if (!server_)
    return nullptr;

  net::IPEndPoint address;
  int net_result = server_->GetLocalAddress(&address);
  if (net_result != net::OK)
    return nullptr;

  return NetAddress::From(address);
}

void HttpServerImpl::OnConnect(int connection_id) {
  DCHECK(connections_.find(connection_id) == connections_.end());

  HttpConnectionPtr connection;
  HttpConnectionDelegatePtr connection_delegate;
  InterfaceRequest<HttpConnectionDelegate> delegate_request =
      GetProxy(&connection_delegate);
  linked_ptr<HttpConnectionImpl> connection_impl(
      new HttpConnectionImpl(connection_id, this, connection_delegate.Pass(),
                             &connection));

  connections_[connection_id] = connection_impl;

  delegate_->OnConnected(connection.Pass(), delegate_request.Pass());
}

void HttpServerImpl::OnHttpRequest(int connection_id,
                                   const net::HttpServerRequestInfo& info) {
  DCHECK(connections_.find(connection_id) != connections_.end());
  connections_[connection_id]->OnReceivedHttpRequest(info);
}

void HttpServerImpl::OnWebSocketRequest(
    int connection_id,
    const net::HttpServerRequestInfo& info) {
  DCHECK(connections_.find(connection_id) != connections_.end());
  connections_[connection_id]->OnReceivedWebSocketRequest(info);
}

void HttpServerImpl::OnWebSocketMessage(int connection_id,
                                        const std::string& data) {
  DCHECK(connections_.find(connection_id) != connections_.end());
  connections_[connection_id]->OnReceivedWebSocketMessage(data);
}

void HttpServerImpl::OnClose(int connection_id) {
  DCHECK(connections_.find(connection_id) != connections_.end());
  connections_.erase(connection_id);
}

void HttpServerImpl::OnConnectionError() {
  delete this;
}

}  // namespace mojo
