/*
 * Copyright (c) 2014, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "core/page/NetworkStateNotifier.h"

#include "core/dom/Document.h"
#include "platform/testing/UnitTestHelpers.h"
#include "public/platform/Platform.h"
#include "public/platform/WebConnectionType.h"
#include "public/platform/WebThread.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "wtf/Functional.h"

namespace blink {

namespace {
const double kNoneMaxBandwidthMbps = 0.0;
const double kBluetoothMaxBandwidthMbps = 1.0;
const double kEthernetMaxBandwidthMbps = 2.0;
}

class StateObserver : public NetworkStateNotifier::NetworkStateObserver {
 public:
  StateObserver()
      : m_observedType(WebConnectionTypeNone),
        m_observedMaxBandwidthMbps(0.0),
        m_callbackCount(0) {}

  virtual void connectionChange(WebConnectionType type,
                                double maxBandwidthMbps) {
    m_observedType = type;
    m_observedMaxBandwidthMbps = maxBandwidthMbps;
    m_callbackCount += 1;

    if (m_closure)
      (*m_closure)();
  }

  WebConnectionType observedType() const { return m_observedType; }

  double observedMaxBandwidth() const { return m_observedMaxBandwidthMbps; }

  int callbackCount() const { return m_callbackCount; }

  void setNotificationCallback(std::unique_ptr<WTF::Closure> closure) {
    m_closure = std::move(closure);
  }

 private:
  std::unique_ptr<WTF::Closure> m_closure;
  WebConnectionType m_observedType;
  double m_observedMaxBandwidthMbps;
  int m_callbackCount;
};

class NetworkStateNotifierTest : public ::testing::Test {
 public:
  NetworkStateNotifierTest()
      : m_document(Document::create()), m_document2(Document::create()) {
    // Initialize connection, so that future calls to setWebConnection issue
    // notifications.
    m_notifier.setWebConnection(WebConnectionTypeUnknown, 0.0);
  }

  ExecutionContext* getExecutionContext() { return m_document.get(); }

  ExecutionContext* executionContext2() { return m_document2.get(); }

 protected:
  void setConnection(WebConnectionType type, double maxBandwidthMbps) {
    m_notifier.setWebConnection(type, maxBandwidthMbps);
    testing::runPendingTasks();
  }

  void addObserverOnNotification(StateObserver* observer,
                                 StateObserver* observerToAdd) {
    observer->setNotificationCallback(bind(
        &NetworkStateNotifier::addObserver, WTF::unretained(&m_notifier),
        WTF::unretained(observerToAdd), wrapPersistent(getExecutionContext())));
  }

  void removeObserverOnNotification(StateObserver* observer,
                                    StateObserver* observerToRemove) {
    observer->setNotificationCallback(
        bind(&NetworkStateNotifier::removeObserver,
             WTF::unretained(&m_notifier), WTF::unretained(observerToRemove),
             wrapPersistent(getExecutionContext())));
  }

  bool verifyObservations(const StateObserver& observer,
                          WebConnectionType type,
                          double maxBandwidthMbps) {
    EXPECT_EQ(observer.observedType(), type);
    EXPECT_EQ(observer.observedMaxBandwidth(), maxBandwidthMbps);
    return observer.observedType() == type &&
           observer.observedMaxBandwidth() == maxBandwidthMbps;
  }

  Persistent<Document> m_document;
  Persistent<Document> m_document2;
  NetworkStateNotifier m_notifier;
};

TEST_F(NetworkStateNotifierTest, AddObserver) {
  StateObserver observer;
  m_notifier.addObserver(&observer, getExecutionContext());
  EXPECT_TRUE(verifyObservations(observer, WebConnectionTypeNone,
                                 kNoneMaxBandwidthMbps));

  setConnection(WebConnectionTypeBluetooth, kBluetoothMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
  EXPECT_EQ(observer.callbackCount(), 1);
}

TEST_F(NetworkStateNotifierTest, RemoveObserver) {
  StateObserver observer1, observer2;
  m_notifier.addObserver(&observer1, getExecutionContext());
  m_notifier.removeObserver(&observer1, getExecutionContext());
  m_notifier.addObserver(&observer2, getExecutionContext());

  setConnection(WebConnectionTypeBluetooth, kBluetoothMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer1, WebConnectionTypeNone,
                                 kNoneMaxBandwidthMbps));
  EXPECT_TRUE(verifyObservations(observer2, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
}

TEST_F(NetworkStateNotifierTest, RemoveSoleObserver) {
  StateObserver observer1;
  m_notifier.addObserver(&observer1, getExecutionContext());
  m_notifier.removeObserver(&observer1, getExecutionContext());

  setConnection(WebConnectionTypeBluetooth, kBluetoothMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer1, WebConnectionTypeNone,
                                 kNoneMaxBandwidthMbps));
}

TEST_F(NetworkStateNotifierTest, AddObserverWhileNotifying) {
  StateObserver observer1, observer2;
  m_notifier.addObserver(&observer1, getExecutionContext());
  addObserverOnNotification(&observer1, &observer2);

  setConnection(WebConnectionTypeBluetooth, kBluetoothMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer1, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
  EXPECT_TRUE(verifyObservations(observer2, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
}

TEST_F(NetworkStateNotifierTest, RemoveSoleObserverWhileNotifying) {
  StateObserver observer1;
  m_notifier.addObserver(&observer1, getExecutionContext());
  removeObserverOnNotification(&observer1, &observer1);

  setConnection(WebConnectionTypeBluetooth, kBluetoothMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer1, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));

  setConnection(WebConnectionTypeEthernet, kEthernetMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer1, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
}

TEST_F(NetworkStateNotifierTest, RemoveCurrentObserverWhileNotifying) {
  StateObserver observer1, observer2;
  m_notifier.addObserver(&observer1, getExecutionContext());
  m_notifier.addObserver(&observer2, getExecutionContext());
  removeObserverOnNotification(&observer1, &observer1);

  setConnection(WebConnectionTypeBluetooth, kBluetoothMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer1, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
  EXPECT_TRUE(verifyObservations(observer2, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));

  setConnection(WebConnectionTypeEthernet, kEthernetMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer1, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
  EXPECT_TRUE(verifyObservations(observer2, WebConnectionTypeEthernet,
                                 kEthernetMaxBandwidthMbps));
}

TEST_F(NetworkStateNotifierTest, RemovePastObserverWhileNotifying) {
  StateObserver observer1, observer2;
  m_notifier.addObserver(&observer1, getExecutionContext());
  m_notifier.addObserver(&observer2, getExecutionContext());
  removeObserverOnNotification(&observer2, &observer1);

  setConnection(WebConnectionTypeBluetooth, kBluetoothMaxBandwidthMbps);
  EXPECT_EQ(observer1.observedType(), WebConnectionTypeBluetooth);
  EXPECT_EQ(observer2.observedType(), WebConnectionTypeBluetooth);

  setConnection(WebConnectionTypeEthernet, kEthernetMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer1, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
  EXPECT_TRUE(verifyObservations(observer2, WebConnectionTypeEthernet,
                                 kEthernetMaxBandwidthMbps));
}

TEST_F(NetworkStateNotifierTest, RemoveFutureObserverWhileNotifying) {
  StateObserver observer1, observer2, observer3;
  m_notifier.addObserver(&observer1, getExecutionContext());
  m_notifier.addObserver(&observer2, getExecutionContext());
  m_notifier.addObserver(&observer3, getExecutionContext());
  removeObserverOnNotification(&observer1, &observer2);

  setConnection(WebConnectionTypeBluetooth, kBluetoothMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer1, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
  EXPECT_TRUE(verifyObservations(observer2, WebConnectionTypeNone,
                                 kNoneMaxBandwidthMbps));
  EXPECT_TRUE(verifyObservations(observer3, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
}

TEST_F(NetworkStateNotifierTest, MultipleContextsAddObserver) {
  StateObserver observer1, observer2;
  m_notifier.addObserver(&observer1, getExecutionContext());
  m_notifier.addObserver(&observer2, executionContext2());

  setConnection(WebConnectionTypeBluetooth, kBluetoothMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer1, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
  EXPECT_TRUE(verifyObservations(observer2, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
}

TEST_F(NetworkStateNotifierTest, RemoveContext) {
  StateObserver observer1, observer2;
  m_notifier.addObserver(&observer1, getExecutionContext());
  m_notifier.addObserver(&observer2, executionContext2());
  m_notifier.removeObserver(&observer2, executionContext2());

  setConnection(WebConnectionTypeBluetooth, kBluetoothMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer1, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
  EXPECT_TRUE(verifyObservations(observer2, WebConnectionTypeNone,
                                 kNoneMaxBandwidthMbps));
}

TEST_F(NetworkStateNotifierTest, RemoveAllContexts) {
  StateObserver observer1, observer2;
  m_notifier.addObserver(&observer1, getExecutionContext());
  m_notifier.addObserver(&observer2, executionContext2());
  m_notifier.removeObserver(&observer1, getExecutionContext());
  m_notifier.removeObserver(&observer2, executionContext2());

  setConnection(WebConnectionTypeBluetooth, kBluetoothMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer1, WebConnectionTypeNone,
                                 kNoneMaxBandwidthMbps));
  EXPECT_TRUE(verifyObservations(observer2, WebConnectionTypeNone,
                                 kNoneMaxBandwidthMbps));
}

TEST_F(NetworkStateNotifierTest, SetOverride) {
  StateObserver observer;
  m_notifier.addObserver(&observer, getExecutionContext());

  m_notifier.setOnLine(true);
  setConnection(WebConnectionTypeBluetooth, kBluetoothMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
  EXPECT_TRUE(m_notifier.onLine());
  EXPECT_EQ(WebConnectionTypeBluetooth, m_notifier.connectionType());
  EXPECT_EQ(kBluetoothMaxBandwidthMbps, m_notifier.maxBandwidth());

  m_notifier.setOverride(true, WebConnectionTypeEthernet,
                         kEthernetMaxBandwidthMbps);
  testing::runPendingTasks();
  EXPECT_TRUE(verifyObservations(observer, WebConnectionTypeEthernet,
                                 kEthernetMaxBandwidthMbps));
  EXPECT_TRUE(m_notifier.onLine());
  EXPECT_EQ(WebConnectionTypeEthernet, m_notifier.connectionType());
  EXPECT_EQ(kEthernetMaxBandwidthMbps, m_notifier.maxBandwidth());

  // When override is active, calls to setOnLine and setConnection are temporary
  // ignored.
  m_notifier.setOnLine(false);
  setConnection(WebConnectionTypeNone, kNoneMaxBandwidthMbps);
  testing::runPendingTasks();
  EXPECT_TRUE(verifyObservations(observer, WebConnectionTypeEthernet,
                                 kEthernetMaxBandwidthMbps));
  EXPECT_TRUE(m_notifier.onLine());
  EXPECT_EQ(WebConnectionTypeEthernet, m_notifier.connectionType());
  EXPECT_EQ(kEthernetMaxBandwidthMbps, m_notifier.maxBandwidth());

  m_notifier.clearOverride();
  testing::runPendingTasks();
  EXPECT_TRUE(verifyObservations(observer, WebConnectionTypeNone,
                                 kNoneMaxBandwidthMbps));
  EXPECT_FALSE(m_notifier.onLine());
  EXPECT_EQ(WebConnectionTypeNone, m_notifier.connectionType());
  EXPECT_EQ(kNoneMaxBandwidthMbps, m_notifier.maxBandwidth());

  m_notifier.removeObserver(&observer, getExecutionContext());
}

TEST_F(NetworkStateNotifierTest, NoExtraNotifications) {
  StateObserver observer;
  m_notifier.addObserver(&observer, getExecutionContext());

  setConnection(WebConnectionTypeBluetooth, kBluetoothMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
  EXPECT_EQ(observer.callbackCount(), 1);

  setConnection(WebConnectionTypeBluetooth, kBluetoothMaxBandwidthMbps);
  EXPECT_EQ(observer.callbackCount(), 1);

  setConnection(WebConnectionTypeEthernet, kEthernetMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer, WebConnectionTypeEthernet,
                                 kEthernetMaxBandwidthMbps));
  EXPECT_EQ(observer.callbackCount(), 2);

  setConnection(WebConnectionTypeEthernet, kEthernetMaxBandwidthMbps);
  EXPECT_EQ(observer.callbackCount(), 2);

  setConnection(WebConnectionTypeBluetooth, kBluetoothMaxBandwidthMbps);
  EXPECT_TRUE(verifyObservations(observer, WebConnectionTypeBluetooth,
                                 kBluetoothMaxBandwidthMbps));
  EXPECT_EQ(observer.callbackCount(), 3);

  m_notifier.removeObserver(&observer, getExecutionContext());
}

TEST_F(NetworkStateNotifierTest, NoNotificationOnInitialization) {
  NetworkStateNotifier notifier;
  Persistent<Document> document(Document::create());
  StateObserver observer;

  notifier.addObserver(&observer, document.get());
  testing::runPendingTasks();
  EXPECT_EQ(observer.callbackCount(), 0);

  notifier.setWebConnection(WebConnectionTypeBluetooth,
                            kBluetoothMaxBandwidthMbps);
  testing::runPendingTasks();
  EXPECT_EQ(observer.callbackCount(), 0);

  notifier.setWebConnection(WebConnectionTypeBluetooth,
                            kBluetoothMaxBandwidthMbps);
  testing::runPendingTasks();
  EXPECT_EQ(observer.callbackCount(), 0);

  notifier.setWebConnection(WebConnectionTypeEthernet,
                            kEthernetMaxBandwidthMbps);
  testing::runPendingTasks();
  EXPECT_EQ(observer.callbackCount(), 1);
  EXPECT_EQ(observer.observedType(), WebConnectionTypeEthernet);
  EXPECT_EQ(observer.observedMaxBandwidth(), kEthernetMaxBandwidthMbps);
}

}  // namespace blink
