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

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/task_runner.h"
#include "base/time/time.h"
#include "net/base/net_errors.h"
#include "net/proxy/dhcpcsvc_init_win.h"
#include "net/proxy/proxy_script_fetcher_impl.h"
#include "net/url_request/url_request_context.h"

#include <windows.h>
#include <winsock2.h>
#include <dhcpcsdk.h>
#pragma comment(lib, "dhcpcsvc.lib")

namespace {

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

}  // namespace

namespace net {

DhcpProxyScriptAdapterFetcher::DhcpProxyScriptAdapterFetcher(
    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_);
}

DhcpProxyScriptAdapterFetcher::~DhcpProxyScriptAdapterFetcher() {
  Cancel();
}

void DhcpProxyScriptAdapterFetcher::Fetch(
    const std::string& adapter_name, const CompletionCallback& callback) {
  DCHECK(CalledOnValidThread());
  DCHECK_EQ(state_, STATE_START);
  result_ = ERR_IO_PENDING;
  pac_script_ = base::string16();
  state_ = STATE_WAIT_DHCP;
  callback_ = callback;

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

void DhcpProxyScriptAdapterFetcher::Cancel() {
  DCHECK(CalledOnValidThread());
  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 DhcpProxyScriptAdapterFetcher::DidFinish() const {
  DCHECK(CalledOnValidThread());
  return state_ == STATE_FINISH;
}

int DhcpProxyScriptAdapterFetcher::GetResult() const {
  DCHECK(CalledOnValidThread());
  return result_;
}

base::string16 DhcpProxyScriptAdapterFetcher::GetPacScript() const {
  DCHECK(CalledOnValidThread());
  return pac_script_;
}

GURL DhcpProxyScriptAdapterFetcher::GetPacURL() const {
  DCHECK(CalledOnValidThread());
  return pac_url_;
}

DhcpProxyScriptAdapterFetcher::DhcpQuery::DhcpQuery() {
}

DhcpProxyScriptAdapterFetcher::DhcpQuery::~DhcpQuery() {
}

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

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

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

void DhcpProxyScriptAdapterFetcher::OnDhcpQueryDone(
    scoped_refptr<DhcpQuery> dhcp_query) {
  DCHECK(CalledOnValidThread());
  // 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_.reset(ImplCreateScriptFetcher());
    script_fetcher_->Fetch(
        pac_url_, &pac_script_,
        base::Bind(&DhcpProxyScriptAdapterFetcher::OnFetcherDone,
                   base::Unretained(this)));
  }
}

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

void DhcpProxyScriptAdapterFetcher::OnFetcherDone(int result) {
  DCHECK(CalledOnValidThread());
  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 DhcpProxyScriptAdapterFetcher::TransitionToFinish() {
  DCHECK(state_ == STATE_WAIT_DHCP || state_ == STATE_WAIT_URL);
  state_ = STATE_FINISH;
  CompletionCallback callback = callback_;
  callback_.Reset();

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

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

ProxyScriptFetcher* DhcpProxyScriptAdapterFetcher::ImplCreateScriptFetcher() {
  return new ProxyScriptFetcherImpl(url_request_context_);
}

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

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

// static
std::string DhcpProxyScriptAdapterFetcher::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;
  scoped_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.
    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 DhcpProxyScriptAdapterFetcher::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
