// Copyright (c) 2011 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/network_delegate_error_observer.h"

#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "net/base/net_errors.h"
#include "net/base/network_delegate.h"

namespace net {

// NetworkDelegateErrorObserver::Core -----------------------------------------

class NetworkDelegateErrorObserver::Core
    : public base::RefCountedThreadSafe<NetworkDelegateErrorObserver::Core> {
 public:
  Core(NetworkDelegate* network_delegate,
       base::SingleThreadTaskRunner* origin_runner);

  void NotifyPACScriptError(int line_number, const base::string16& error);

  void Shutdown();

 private:
  friend class base::RefCountedThreadSafe<NetworkDelegateErrorObserver::Core>;

  virtual ~Core();

  NetworkDelegate* network_delegate_;
  scoped_refptr<base::SingleThreadTaskRunner> origin_runner_;

  DISALLOW_COPY_AND_ASSIGN(Core);
};

NetworkDelegateErrorObserver::Core::Core(
    NetworkDelegate* network_delegate,
    base::SingleThreadTaskRunner* origin_runner)
    : network_delegate_(network_delegate), origin_runner_(origin_runner) {
  DCHECK(origin_runner);
}

NetworkDelegateErrorObserver::Core::~Core() = default;

void NetworkDelegateErrorObserver::Core::NotifyPACScriptError(
    int line_number,
    const base::string16& error) {
  if (!origin_runner_->BelongsToCurrentThread()) {
    origin_runner_->PostTask(FROM_HERE, base::Bind(&Core::NotifyPACScriptError,
                                                   this, line_number, error));
    return;
  }
  if (network_delegate_)
    network_delegate_->NotifyPACScriptError(line_number, error);
}

void NetworkDelegateErrorObserver::Core::Shutdown() {
  CHECK(origin_runner_->BelongsToCurrentThread());
  network_delegate_ = NULL;
}

// NetworkDelegateErrorObserver -----------------------------------------------

NetworkDelegateErrorObserver::NetworkDelegateErrorObserver(
    NetworkDelegate* network_delegate,
    base::SingleThreadTaskRunner* origin_runner)
    : core_(new Core(network_delegate, origin_runner)) {
}

NetworkDelegateErrorObserver::~NetworkDelegateErrorObserver() {
  core_->Shutdown();
}

// static
std::unique_ptr<ProxyResolverErrorObserver>
NetworkDelegateErrorObserver::Create(
    NetworkDelegate* network_delegate,
    const scoped_refptr<base::SingleThreadTaskRunner>& origin_runner) {
  return std::make_unique<NetworkDelegateErrorObserver>(network_delegate,
                                                        origin_runner.get());
}

void NetworkDelegateErrorObserver::OnPACScriptError(
    int line_number,
    const base::string16& error) {
  core_->NotifyPACScriptError(line_number, error);
}

}  // namespace net
