// Copyright 2016 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 "components/grpc_support/include/bidirectional_stream_c.h"

#include <stdbool.h>

#include <memory>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "components/grpc_support/bidirectional_stream.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/http/bidirectional_stream.h"
#include "net/http/bidirectional_stream_request_info.h"
#include "net/http/http_network_session.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/http/http_transaction_factory.h"
#include "net/http/http_util.h"
#include "net/spdy/core/spdy_header_block.h"
#include "net/ssl/ssl_info.h"
#include "net/url_request/http_user_agent_settings.h"
#include "net/url_request/url_request_context.h"
#include "url/gurl.h"

namespace {

class HeadersArray : public bidirectional_stream_header_array {
 public:
  HeadersArray(const net::SpdyHeaderBlock& header_block);
  ~HeadersArray();

 private:
  DISALLOW_COPY_AND_ASSIGN(HeadersArray);
  base::StringPairs headers_strings_;
};

HeadersArray::HeadersArray(const net::SpdyHeaderBlock& header_block)
    : headers_strings_(header_block.size()) {
  // Count and headers are inherited from parent structure.
  count = capacity = header_block.size();
  headers = new bidirectional_stream_header[count];
  size_t i = 0;
  // Copy headers into |headers_strings_| because string pieces are not
  // '\0'-terminated.
  for (const auto& it : header_block) {
    headers_strings_[i].first = it.first.as_string();
    headers_strings_[i].second = it.second.as_string();
    headers[i].key = headers_strings_[i].first.c_str();
    headers[i].value = headers_strings_[i].second.c_str();
    ++i;
  }
}

HeadersArray::~HeadersArray() {
  delete[] headers;
}

class BidirectionalStreamAdapter
    : public grpc_support::BidirectionalStream::Delegate {
 public:
  BidirectionalStreamAdapter(stream_engine* engine,
                             void* annotation,
                             bidirectional_stream_callback* callback);

  virtual ~BidirectionalStreamAdapter();

  void OnStreamReady() override;

  void OnHeadersReceived(const net::SpdyHeaderBlock& headers_block,
                         const char* negotiated_protocol) override;

  void OnDataRead(char* data, int size) override;

  void OnDataSent(const char* data) override;

  void OnTrailersReceived(const net::SpdyHeaderBlock& trailers_block) override;

  void OnSucceeded() override;

  void OnFailed(int error) override;

  void OnCanceled() override;

  bidirectional_stream* c_stream() const { return c_stream_.get(); }

  static grpc_support::BidirectionalStream* GetStream(
      bidirectional_stream* stream);

  static void DestroyAdapterForStream(bidirectional_stream* stream);

 private:
  void DestroyOnNetworkThread();

  // None of these objects are owned by |this|.
  net::URLRequestContextGetter* request_context_getter_;
  grpc_support::BidirectionalStream* bidirectional_stream_;
  // C side
  std::unique_ptr<bidirectional_stream> c_stream_;
  bidirectional_stream_callback* c_callback_;
};

BidirectionalStreamAdapter::BidirectionalStreamAdapter(
    stream_engine* engine,
    void* annotation,
    bidirectional_stream_callback* callback)
    : request_context_getter_(
          reinterpret_cast<net::URLRequestContextGetter*>(engine->obj)),
      c_stream_(base::MakeUnique<bidirectional_stream>()),
      c_callback_(callback) {
  DCHECK(request_context_getter_);
  bidirectional_stream_ =
      new grpc_support::BidirectionalStream(request_context_getter_, this);
  c_stream_->obj = this;
  c_stream_->annotation = annotation;
}

BidirectionalStreamAdapter::~BidirectionalStreamAdapter() {}

void BidirectionalStreamAdapter::OnStreamReady() {
  DCHECK(c_callback_->on_response_headers_received);
  c_callback_->on_stream_ready(c_stream());
}

void BidirectionalStreamAdapter::OnHeadersReceived(
    const net::SpdyHeaderBlock& headers_block,
    const char* negotiated_protocol) {
  DCHECK(c_callback_->on_response_headers_received);
  HeadersArray response_headers(headers_block);
  c_callback_->on_response_headers_received(c_stream(), &response_headers,
                                            negotiated_protocol);
}

void BidirectionalStreamAdapter::OnDataRead(char* data, int size) {
  DCHECK(c_callback_->on_read_completed);
  c_callback_->on_read_completed(c_stream(), data, size);
}

void BidirectionalStreamAdapter::OnDataSent(const char* data) {
  DCHECK(c_callback_->on_write_completed);
  c_callback_->on_write_completed(c_stream(), data);
}

void BidirectionalStreamAdapter::OnTrailersReceived(
    const net::SpdyHeaderBlock& trailers_block) {
  DCHECK(c_callback_->on_response_trailers_received);
  HeadersArray response_trailers(trailers_block);
  c_callback_->on_response_trailers_received(c_stream(), &response_trailers);
}

void BidirectionalStreamAdapter::OnSucceeded() {
  DCHECK(c_callback_->on_succeded);
  c_callback_->on_succeded(c_stream());
}

void BidirectionalStreamAdapter::OnFailed(int error) {
  DCHECK(c_callback_->on_failed);
  c_callback_->on_failed(c_stream(), error);
}

void BidirectionalStreamAdapter::OnCanceled() {
  DCHECK(c_callback_->on_canceled);
  c_callback_->on_canceled(c_stream());
}

grpc_support::BidirectionalStream* BidirectionalStreamAdapter::GetStream(
    bidirectional_stream* stream) {
  DCHECK(stream);
  BidirectionalStreamAdapter* adapter =
      static_cast<BidirectionalStreamAdapter*>(stream->obj);
  DCHECK(adapter->c_stream() == stream);
  DCHECK(adapter->bidirectional_stream_);
  return adapter->bidirectional_stream_;
}

void BidirectionalStreamAdapter::DestroyAdapterForStream(
    bidirectional_stream* stream) {
  DCHECK(stream);
  BidirectionalStreamAdapter* adapter =
      static_cast<BidirectionalStreamAdapter*>(stream->obj);
  DCHECK(adapter->c_stream() == stream);
  // Destroy could be called from any thread, including network thread (if
  // posting task to executor throws an exception), but is posted, so |this|
  // is valid until calling task is complete.
  adapter->bidirectional_stream_->Destroy();
  adapter->request_context_getter_->GetNetworkTaskRunner()->PostTask(
      FROM_HERE, base::Bind(&BidirectionalStreamAdapter::DestroyOnNetworkThread,
                            base::Unretained(adapter)));
}

void BidirectionalStreamAdapter::DestroyOnNetworkThread() {
  DCHECK(request_context_getter_->GetNetworkTaskRunner()
             ->BelongsToCurrentThread());
  delete this;
}

}  // namespace

bidirectional_stream* bidirectional_stream_create(
    stream_engine* engine,
    void* annotation,
    bidirectional_stream_callback* callback) {
  // Allocate new C++ adapter that will invoke |callback|.
  BidirectionalStreamAdapter* stream_adapter =
      new BidirectionalStreamAdapter(engine, annotation, callback);
  return stream_adapter->c_stream();
}

int bidirectional_stream_destroy(bidirectional_stream* stream) {
  BidirectionalStreamAdapter::DestroyAdapterForStream(stream);
  return 1;
}

void bidirectional_stream_disable_auto_flush(bidirectional_stream* stream,
                                             bool disable_auto_flush) {
  BidirectionalStreamAdapter::GetStream(stream)->disable_auto_flush(
      disable_auto_flush);
}

void bidirectional_stream_delay_request_headers_until_flush(
    bidirectional_stream* stream,
    bool delay_headers_until_flush) {
  BidirectionalStreamAdapter::GetStream(stream)->delay_headers_until_flush(
      delay_headers_until_flush);
}

int bidirectional_stream_start(bidirectional_stream* stream,
                               const char* url,
                               int priority,
                               const char* method,
                               const bidirectional_stream_header_array* headers,
                               bool end_of_stream) {
  grpc_support::BidirectionalStream* internal_stream =
      BidirectionalStreamAdapter::GetStream(stream);
  net::HttpRequestHeaders request_headers;
  if (headers) {
    for (size_t i = 0; i < headers->count; ++i) {
      std::string name(headers->headers[i].key);
      std::string value(headers->headers[i].value);
      if (!net::HttpUtil::IsValidHeaderName(name) ||
          !net::HttpUtil::IsValidHeaderValue(value)) {
        DLOG(ERROR) << "Invalid Header " << name << "=" << value;
        return i + 1;
      }
      request_headers.SetHeader(name, value);
    }
  }
  return internal_stream->Start(url, priority, method, request_headers,
                                end_of_stream);
}

int bidirectional_stream_read(bidirectional_stream* stream,
                              char* buffer,
                              int capacity) {
  return BidirectionalStreamAdapter::GetStream(stream)->ReadData(buffer,
                                                                 capacity);
}

int bidirectional_stream_write(bidirectional_stream* stream,
                               const char* buffer,
                               int count,
                               bool end_of_stream) {
  return BidirectionalStreamAdapter::GetStream(stream)->WriteData(
      buffer, count, end_of_stream);
}

void bidirectional_stream_flush(bidirectional_stream* stream) {
  return BidirectionalStreamAdapter::GetStream(stream)->Flush();
}

void bidirectional_stream_cancel(bidirectional_stream* stream) {
  BidirectionalStreamAdapter::GetStream(stream)->Cancel();
}
