// 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/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/free_deleter.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/task_runner.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/time/time.h"
#include "net/base/net_errors.h"
#include "net/proxy_resolution/dhcpcsvc_init_win.h"
#include "net/proxy_resolution/pac_file_fetcher_impl.h"
#include "net/url_request/url_request_context.h"

#include <windows.h>
#include <winsock2.h>
#include <dhcpcsdk.h>

#include "starboard/memory.h"
#include "starboard/types.h"

namespace {

// Maximum amount of time to wait for response from the Win32 DHCP API.
const int kTimeoutMs = 2000;

}  // namespace

namespace net {

DhcpPacFileAdapterFetcher::DhcpPacFileAdapterFetcher(
    URLRequestContext* url_request_context,
    scoped_refptr<base::TaskRunner> task_runner)
    : task_runner_(task_runner),
      state_(STATE_START),
      result_(ERR_IO_PENDING),
      url_request_context_(url_request_context) {
  DCHECK(url_request_context_);
}

DhcpPacFileAdapterFetcher::~DhcpPacFileAdapterFetcher() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  Cancel();
}

void DhcpPacFileAdapterFetcher::Fetch(
    const std::string& adapter_name,
    CompletionOnceCallback callback,
    const NetworkTrafficAnnotationTag traffic_annotation) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK_EQ(state_, STATE_START);
  result_ = ERR_IO_PENDING;
  pac_script_ = base::string16();
  state_ = STATE_WAIT_DHCP;
  callback_ = std::move(callback);

  wait_timer_.Start(FROM_HERE, ImplGetTimeout(), this,
                    &DhcpPacFileAdapterFetcher::OnTimeout);
  scoped_refptr<DhcpQuery> dhcp_query(ImplCreateDhcpQuery());
  task_runner_->PostTaskAndReply(
      FROM_HERE,
      base::Bind(&DhcpPacFileAdapterFetcher::DhcpQuery::GetPacURLForAdapter,
                 dhcp_query.get(), adapter_name),
      base::Bind(&DhcpPacFileAdapterFetcher::OnDhcpQueryDone, AsWeakPtr(),
                 dhcp_query, traffic_annotation));
}

void DhcpPacFileAdapterFetcher::Cancel() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  callback_.Reset();
  wait_timer_.Stop();
  script_fetcher_.reset();

  switch (state_) {
    case STATE_WAIT_DHCP:
      // Nothing to do here, we let the worker thread run to completion,
      // the task it posts back when it completes will check the state.
      break;
    case STATE_WAIT_URL:
      break;
    case STATE_START:
    case STATE_FINISH:
    case STATE_CANCEL:
      break;
  }

  if (state_ != STATE_FINISH) {
    result_ = ERR_ABORTED;
    state_ = STATE_CANCEL;
  }
}

bool DhcpPacFileAdapterFetcher::DidFinish() const {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  return state_ == STATE_FINISH;
}

int DhcpPacFileAdapterFetcher::GetResult() const {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  return result_;
}

base::string16 DhcpPacFileAdapterFetcher::GetPacScript() const {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  return pac_script_;
}

GURL DhcpPacFileAdapterFetcher::GetPacURL() const {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  return pac_url_;
}

DhcpPacFileAdapterFetcher::DhcpQuery::DhcpQuery() {}

void DhcpPacFileAdapterFetcher::DhcpQuery::GetPacURLForAdapter(
    const std::string& adapter_name) {
  url_ = ImplGetPacURLFromDhcp(adapter_name);
}

const std::string& DhcpPacFileAdapterFetcher::DhcpQuery::url() const {
  return url_;
}

std::string DhcpPacFileAdapterFetcher::DhcpQuery::ImplGetPacURLFromDhcp(
    const std::string& adapter_name) {
  return DhcpPacFileAdapterFetcher::GetPacURLFromDhcp(adapter_name);
}

DhcpPacFileAdapterFetcher::DhcpQuery::~DhcpQuery() {}

void DhcpPacFileAdapterFetcher::OnDhcpQueryDone(
    scoped_refptr<DhcpQuery> dhcp_query,
    const NetworkTrafficAnnotationTag traffic_annotation) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  // Because we can't cancel the call to the Win32 API, we can expect
  // it to finish while we are in a few different states.  The expected
  // one is WAIT_DHCP, but it could be in CANCEL if Cancel() was called,
  // or FINISH if timeout occurred.
  DCHECK(state_ == STATE_WAIT_DHCP || state_ == STATE_CANCEL ||
         state_ == STATE_FINISH);
  if (state_ != STATE_WAIT_DHCP)
    return;

  wait_timer_.Stop();

  pac_url_ = GURL(dhcp_query->url());
  if (pac_url_.is_empty() || !pac_url_.is_valid()) {
    result_ = ERR_PAC_NOT_IN_DHCP;
    TransitionToFinish();
  } else {
    state_ = STATE_WAIT_URL;
    script_fetcher_ = ImplCreateScriptFetcher();
    script_fetcher_->Fetch(pac_url_, &pac_script_,
                           base::Bind(&DhcpPacFileAdapterFetcher::OnFetcherDone,
                                      base::Unretained(this)),
                           traffic_annotation);
  }
}

void DhcpPacFileAdapterFetcher::OnTimeout() {
  DCHECK_EQ(state_, STATE_WAIT_DHCP);
  result_ = ERR_TIMED_OUT;
  TransitionToFinish();
}

void DhcpPacFileAdapterFetcher::OnFetcherDone(int result) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(state_ == STATE_WAIT_URL || state_ == STATE_CANCEL);
  if (state_ == STATE_CANCEL)
    return;

  // At this point, pac_script_ has already been written to.
  script_fetcher_.reset();
  result_ = result;
  TransitionToFinish();
}

void DhcpPacFileAdapterFetcher::TransitionToFinish() {
  DCHECK(state_ == STATE_WAIT_DHCP || state_ == STATE_WAIT_URL);
  state_ = STATE_FINISH;

  // Be careful not to touch any member state after this, as the client
  // may delete us during this callback.
  std::move(callback_).Run(result_);
}

DhcpPacFileAdapterFetcher::State DhcpPacFileAdapterFetcher::state() const {
  return state_;
}

std::unique_ptr<PacFileFetcher>
DhcpPacFileAdapterFetcher::ImplCreateScriptFetcher() {
  return PacFileFetcherImpl::Create(url_request_context_);
}

DhcpPacFileAdapterFetcher::DhcpQuery*
DhcpPacFileAdapterFetcher::ImplCreateDhcpQuery() {
  return new DhcpQuery();
}

base::TimeDelta DhcpPacFileAdapterFetcher::ImplGetTimeout() const {
  return base::TimeDelta::FromMilliseconds(kTimeoutMs);
}

// static
std::string DhcpPacFileAdapterFetcher::GetPacURLFromDhcp(
    const std::string& adapter_name) {
  EnsureDhcpcsvcInit();

  std::wstring adapter_name_wide = base::SysMultiByteToWide(adapter_name,
                                                            CP_ACP);

  DHCPCAPI_PARAMS_ARRAY send_params = { 0, NULL };

  DHCPCAPI_PARAMS wpad_params = { 0 };
  wpad_params.OptionId = 252;
  wpad_params.IsVendor = FALSE;  // Surprising, but intentional.

  DHCPCAPI_PARAMS_ARRAY request_params = { 0 };
  request_params.nParams = 1;
  request_params.Params = &wpad_params;

  // The maximum message size is typically 4096 bytes on Windows per
  // http://support.microsoft.com/kb/321592
  DWORD result_buffer_size = 4096;
  std::unique_ptr<BYTE, base::FreeDeleter> result_buffer;
  int retry_count = 0;
  DWORD res = NO_ERROR;
  do {
    result_buffer.reset(
        static_cast<BYTE*>(malloc(result_buffer_size)));

    // Note that while the DHCPCAPI_REQUEST_SYNCHRONOUS flag seems to indicate
    // there might be an asynchronous mode, there seems to be (at least in
    // terms of well-documented use of this API) only a synchronous mode, with
    // an optional "async notifications later if the option changes" mode.
    // Even IE9, which we hope to emulate as IE is the most widely deployed
    // previous implementation of the DHCP aspect of WPAD and the only one
    // on Windows (Konqueror is the other, on Linux), uses this API with the
    // synchronous flag.  There seem to be several Microsoft Knowledge Base
    // articles about calls to this function failing when other flags are used
    // (e.g. http://support.microsoft.com/kb/885270) so we won't take any
    // chances on non-standard, poorly documented usage.
    base::ScopedBlockingCall scoped_blocking_call(
        base::BlockingType::MAY_BLOCK);
    res = ::DhcpRequestParams(DHCPCAPI_REQUEST_SYNCHRONOUS,
                              NULL,
                              const_cast<LPWSTR>(adapter_name_wide.c_str()),
                              NULL,
                              send_params, request_params,
                              result_buffer.get(), &result_buffer_size,
                              NULL);
    ++retry_count;
  } while (res == ERROR_MORE_DATA && retry_count <= 3);

  if (res != NO_ERROR) {
    VLOG(1) << "Error fetching PAC URL from DHCP: " << res;
  } else if (wpad_params.nBytesData) {
    return SanitizeDhcpApiString(
        reinterpret_cast<const char*>(wpad_params.Data),
        wpad_params.nBytesData);
  }

  return "";
}

// static
std::string DhcpPacFileAdapterFetcher::SanitizeDhcpApiString(
    const char* data,
    size_t count_bytes) {
  // The result should be ASCII, not wide character.  Some DHCP
  // servers appear to count the trailing NULL in nBytesData, others
  // do not.  A few (we've had one report, http://crbug.com/297810)
  // do not NULL-terminate but may \n-terminate.
  //
  // Belt and suspenders and elastic waistband: First, ensure we
  // NULL-terminate after nBytesData; this is the inner constructor
  // with nBytesData as a parameter.  Then, return only up to the
  // first null in case of embedded NULLs; this is the outer
  // constructor that takes the result of c_str() on the inner.  If
  // the server is giving us back a buffer with embedded NULLs,
  // something is broken anyway.  Finally, trim trailing whitespace.
  std::string result(std::string(data, count_bytes).c_str());
  base::TrimWhitespaceASCII(result, base::TRIM_TRAILING, &result);
  return result;
}

}  // namespace net
