// Copyright 2017 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/quic/quic_stream_factory.h"

#include <fuzzer/FuzzedDataProvider.h>

#include "base/stl_util.h"
#include "net/base/network_isolation_key.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/do_nothing_ct_verifier.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/cert/x509_certificate.h"
#include "net/dns/context_host_resolver.h"
#include "net/dns/fuzzed_host_resolver_util.h"
#include "net/http/http_server_properties.h"
#include "net/http/transport_security_state.h"
#include "net/quic/mock_crypto_client_stream_factory.h"
#include "net/quic/quic_context.h"
#include "net/quic/quic_http_stream.h"
#include "net/quic/test_task_runner.h"
#include "net/socket/fuzzed_datagram_client_socket.h"
#include "net/socket/fuzzed_socket_factory.h"
#include "net/socket/socket_tag.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/test/gtest_util.h"
#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"

namespace net {

namespace {

const char kCertData[] = {
#include "net/data/ssl/certificates/wildcard.inc"
};

}  // namespace

namespace test {

const char kServerHostName[] = "www.example.org";
const int kServerPort = 443;
const char kUrl[] = "https://www.example.org/";
// TODO(nedwilliamson): Add POST here after testing
// whether that can lead blocking while waiting for
// the callbacks.
const char kMethod[] = "GET";
const size_t kBufferSize = 4096;
const int kCertVerifyFlags = 0;

// Static initialization for persistent factory data
struct Env {
  Env() : host_port_pair(kServerHostName, kServerPort), random_generator(0) {
    clock.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
    ssl_config_service = std::make_unique<SSLConfigServiceDefaults>();
    crypto_client_stream_factory.set_use_mock_crypter(true);
    cert_verifier = std::make_unique<MockCertVerifier>();
    cert_transparency_verifier = std::make_unique<DoNothingCTVerifier>();
    verify_details.cert_verify_result.verified_cert =
        X509Certificate::CreateFromBytes(kCertData, base::size(kCertData));
    CHECK(verify_details.cert_verify_result.verified_cert);
    verify_details.cert_verify_result.is_issued_by_known_root = true;
  }

  quic::MockClock clock;
  std::unique_ptr<SSLConfigService> ssl_config_service;
  ProofVerifyDetailsChromium verify_details;
  MockCryptoClientStreamFactory crypto_client_stream_factory;
  HostPortPair host_port_pair;
  quic::test::MockRandom random_generator;
  NetLogWithSource net_log;
  std::unique_ptr<CertVerifier> cert_verifier;
  TransportSecurityState transport_security_state;
  quic::QuicTagVector connection_options;
  quic::QuicTagVector client_connection_options;
  std::unique_ptr<CTVerifier> cert_transparency_verifier;
  DefaultCTPolicyEnforcer ct_policy_enforcer;
  QuicContext quic_context;
};

static struct Env* env = new Env();

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  FuzzedDataProvider data_provider(data, size);

  std::unique_ptr<ContextHostResolver> host_resolver =
      CreateFuzzedContextHostResolver(HostResolver::ManagerOptions(), nullptr,
                                      &data_provider,
                                      true /* enable_caching */);
  FuzzedSocketFactory socket_factory(&data_provider);

  // Initialize this on each loop since some options mutate this.
  HttpServerProperties http_server_properties;

  QuicParams params;
  params.max_server_configs_stored_in_properties =
      data_provider.ConsumeBool() ? 1 : 0;
  params.close_sessions_on_ip_change = data_provider.ConsumeBool();
  params.allow_server_migration = data_provider.ConsumeBool();
  params.race_cert_verification = data_provider.ConsumeBool();
  params.estimate_initial_rtt = data_provider.ConsumeBool();
  params.headers_include_h2_stream_dependency = data_provider.ConsumeBool();
  params.enable_socket_recv_optimization = data_provider.ConsumeBool();
  params.race_stale_dns_on_connection = data_provider.ConsumeBool();

  env->crypto_client_stream_factory.AddProofVerifyDetails(&env->verify_details);

  params.goaway_sessions_on_ip_change = false;
  params.migrate_sessions_early_v2 = false;
  params.migrate_sessions_on_network_change_v2 = false;
  params.retry_on_alternate_network_before_handshake = false;
  params.migrate_idle_sessions = false;
  params.go_away_on_path_degrading = false;

  if (!params.close_sessions_on_ip_change) {
    params.goaway_sessions_on_ip_change = data_provider.ConsumeBool();
    if (!params.goaway_sessions_on_ip_change) {
      params.migrate_sessions_on_network_change_v2 =
          data_provider.ConsumeBool();
      if (params.migrate_sessions_on_network_change_v2) {
        params.migrate_sessions_early_v2 = data_provider.ConsumeBool();
        params.retry_on_alternate_network_before_handshake =
            data_provider.ConsumeBool();
        params.migrate_idle_sessions = data_provider.ConsumeBool();
      }
    }
  }

  if (!params.migrate_sessions_early_v2) {
    params.go_away_on_path_degrading = data_provider.ConsumeBool();
  }

  std::unique_ptr<QuicStreamFactory> factory =
      std::make_unique<QuicStreamFactory>(
          env->net_log.net_log(), host_resolver.get(),
          env->ssl_config_service.get(), &socket_factory,
          &http_server_properties, env->cert_verifier.get(),
          &env->ct_policy_enforcer, &env->transport_security_state,
          env->cert_transparency_verifier.get(), nullptr,
          &env->crypto_client_stream_factory, &env->quic_context, params);

  SetQuicReloadableFlag(quic_supports_tls_handshake, true);
  SetQuicRestartFlag(quic_coalesce_stream_frames_2, true);
  QuicStreamRequest request(factory.get());
  TestCompletionCallback callback;
  NetErrorDetails net_error_details;
  quic::ParsedQuicVersionVector versions = quic::AllSupportedVersions();
  quic::ParsedQuicVersion version =
      versions[data_provider.ConsumeIntegralInRange<size_t>(
          0, versions.size() - 1)];
  request.Request(
      env->host_port_pair, version, PRIVACY_MODE_DISABLED, DEFAULT_PRIORITY,
      SocketTag(), NetworkIsolationKey(), false /* disable_secure_dns */,
      kCertVerifyFlags, GURL(kUrl), env->net_log, &net_error_details,
      /*failed_on_default_network_callback=*/CompletionOnceCallback(),
      callback.callback());

  callback.WaitForResult();
  std::unique_ptr<QuicChromiumClientSession::Handle> session =
      request.ReleaseSessionHandle();
  if (!session)
    return 0;
  std::unique_ptr<HttpStream> stream(new QuicHttpStream(std::move(session)));

  HttpRequestInfo request_info;
  request_info.method = kMethod;
  request_info.url = GURL(kUrl);
  request_info.traffic_annotation =
      MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY, env->net_log,
                           CompletionOnceCallback());

  HttpResponseInfo response;
  HttpRequestHeaders request_headers;
  if (OK !=
      stream->SendRequest(request_headers, &response, callback.callback()))
    return 0;

  // TODO(nedwilliamson): attempt connection migration here
  int rv = stream->ReadResponseHeaders(callback.callback());
  if (rv != OK && rv != ERR_IO_PENDING) {
    return 0;
  }
  callback.WaitForResult();

  scoped_refptr<net::IOBuffer> buffer =
      base::MakeRefCounted<net::IOBuffer>(kBufferSize);
  rv = stream->ReadResponseBody(buffer.get(), kBufferSize, callback.callback());
  if (rv == ERR_IO_PENDING)
    callback.WaitForResult();

  return 0;
}

}  // namespace test
}  // namespace net
