// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "extensions/browser/api/socket/socket.h"

#include "base/functional/bind.h"
#include "base/lazy_instance.h"
#include "base/numerics/safe_conversions.h"
#include "extensions/browser/api/api_resource_manager.h"
#include "net/base/address_list.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/socket/socket.h"

namespace extensions {

const char kSocketTypeNotSupported[] = "Socket type does not support this API";

static base::LazyInstance<
    BrowserContextKeyedAPIFactory<ApiResourceManager<Socket>>>::DestructorAtExit
    g_factory = LAZY_INSTANCE_INITIALIZER;

// static
template <>
BrowserContextKeyedAPIFactory<ApiResourceManager<Socket>>*
ApiResourceManager<Socket>::GetFactoryInstance() {
  return g_factory.Pointer();
}

Socket::Socket(const std::string& owner_extension_id)
    : ApiResource(owner_extension_id) {}

Socket::~Socket() {
  // Derived destructors should make sure the socket has been closed.
  DCHECK(!is_connected_);
}

void Socket::Write(scoped_refptr<net::IOBuffer> io_buffer,
                   size_t byte_count,
                   net::CompletionOnceCallback callback) {
  DCHECK(!callback.is_null());
  write_queue_.emplace(io_buffer, byte_count, std::move(callback));
  WriteData();
}

void Socket::WriteData() {
  // IO is pending.
  if (io_buffer_write_.get())
    return;

  WriteRequest& request = write_queue_.front();

  DCHECK(request.byte_count >= request.bytes_written);
  auto span = request.io_buffer->span()
                  .first(request.byte_count)
                  .subspan(request.bytes_written);
  io_buffer_write_ =
      base::MakeRefCounted<net::WrappedIOBuffer>(std::move(span));
  int result = WriteImpl(
      io_buffer_write_.get(), io_buffer_write_->size(),
      base::BindOnce(&Socket::OnWriteComplete, base::Unretained(this)));

  if (result != net::ERR_IO_PENDING)
    OnWriteComplete(result);
}

void Socket::OnWriteComplete(int result) {
  io_buffer_write_.reset();

  WriteRequest& request = write_queue_.front();

  if (result >= 0) {
    request.bytes_written += static_cast<size_t>(result);
    if (request.bytes_written < request.byte_count) {
      WriteData();
      return;
    }
    DCHECK(request.bytes_written == request.byte_count);
    result = base::checked_cast<int>(request.bytes_written);
  }

  std::move(request.callback).Run(result);
  write_queue_.pop();

  if (!write_queue_.empty())
    WriteData();
}

void Socket::SetKeepAlive(bool enable,
                          int delay,
                          SetKeepAliveCallback callback) {
  std::move(callback).Run(false);
}

void Socket::SetNoDelay(bool no_delay, SetNoDelayCallback callback) {
  std::move(callback).Run(false);
}

void Socket::Listen(const std::string& address,
                    uint16_t port,
                    int backlog,
                    ListenCallback callback) {
  std::move(callback).Run(net::ERR_FAILED, kSocketTypeNotSupported);
}

void Socket::Accept(AcceptCompletionCallback callback) {
  std::move(callback).Run(net::ERR_FAILED, mojo::NullRemote() /* socket */,
                          std::nullopt, mojo::ScopedDataPipeConsumerHandle(),
                          mojo::ScopedDataPipeProducerHandle());
}

// static
bool Socket::StringAndPortToIPEndPoint(const std::string& ip_address_str,
                                       uint16_t port,
                                       net::IPEndPoint* ip_end_point) {
  DCHECK(ip_end_point);
  net::IPAddress ip_address;
  if (!ip_address.AssignFromIPLiteral(ip_address_str))
    return false;

  *ip_end_point = net::IPEndPoint(ip_address, port);
  return true;
}

void Socket::IPEndPointToStringAndPort(const net::IPEndPoint& address,
                                       std::string* ip_address_str,
                                       uint16_t* port) {
  DCHECK(ip_address_str);
  DCHECK(port);
  *ip_address_str = address.ToStringWithoutPort();
  if (ip_address_str->empty()) {
    *port = 0;
  } else {
    *port = address.port();
  }
}

Socket::WriteRequest::WriteRequest(scoped_refptr<net::IOBuffer> io_buffer,
                                   size_t byte_count,
                                   net::CompletionOnceCallback callback)
    : io_buffer(io_buffer),
      byte_count(byte_count),
      callback(std::move(callback)) {}

Socket::WriteRequest::WriteRequest(WriteRequest&& other) = default;

Socket::WriteRequest::~WriteRequest() = default;

// static
net::NetworkTrafficAnnotationTag Socket::GetNetworkTrafficAnnotationTag() {
  return net::DefineNetworkTrafficAnnotation("chrome_apps_socket_api", R"(
        semantics {
          sender: "Chrome Apps Socket API"
          description:
            "Chrome Apps can use this API to send and receive data over "
            "the network using TCP and UDP connections."
          trigger: "A request from a Chrome App."
          data: "Any data that the app sends."
          destination: OTHER
          destination_other:
            "Data can be sent to any destination included in the app manifest."
        }
        policy {
          cookies_allowed: NO
          setting:
            "No settings control. Chrome Connectivity Diagnostics component "
            "uses this API. Other than that, this request will not be sent if "
            "the user does not install a Chrome App that uses the Socket API."
          chrome_policy {
            ExtensionInstallBlocklist {
              ExtensionInstallBlocklist: {
                entries: '*'
              }
            }
          }
        })");
}

}  // namespace extensions
