// Copyright 2015 The Chromium OS 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 "examples/ubuntu/netlink_network.h"

#include <weave/provider/task_runner.h>
#include <base/bind.h>
#include <netlink/route/link.h>

#include "examples/ubuntu/ssl_stream.h"

namespace weave {
namespace examples {

void NetlinkNetworkImpl::Deleter::operator()(nl_sock* s) {
  nl_close(s);
  nl_socket_free(s);
}

void NetlinkNetworkImpl::Deleter::operator()(nl_cache* c) {
  nl_cache_put(c);
}

void NetlinkNetworkImpl::Deleter::operator()(rtnl_link* l) {
  rtnl_link_put(l);
}

NetlinkNetworkImpl::NetlinkNetworkImpl(weave::provider::TaskRunner* task_runner)
    : task_runner_(task_runner) {
  nl_sock_.reset(nl_socket_alloc());
  CHECK(nl_sock_);
  CHECK_EQ(nl_connect(nl_sock_.get(), NETLINK_ROUTE), 0);
  nl_cache* nl_cache;
  CHECK_EQ(rtnl_link_alloc_cache(nl_sock_.get(), AF_UNSPEC, &nl_cache), 0);
  nl_cache_.reset(nl_cache);
  UpdateNetworkState();
}

void NetlinkNetworkImpl::AddConnectionChangedCallback(
    const ConnectionChangedCallback& callback) {
  callbacks_.push_back(callback);
}

void NetlinkNetworkImpl::UpdateNetworkState() {
  // TODO(proppy): pick up interface with the default route instead of index 0.
  // TODO(proppy): test actual internet connection.
  // TODO(proppy): subscribe to interface changes instead of polling.
  network_state_ = GetInterfaceState(0);
  task_runner_->PostDelayedTask(
      FROM_HERE, base::Bind(&NetlinkNetworkImpl::UpdateNetworkState,
                            weak_ptr_factory_.GetWeakPtr()),
      base::TimeDelta::FromSeconds(10));
  for (const auto& cb : callbacks_)
    cb.Run();
}

weave::provider::Network::State NetlinkNetworkImpl::GetInterfaceState(
    int if_index) {
  auto refill_result = nl_cache_refill(nl_sock_.get(), nl_cache_.get());
  if (refill_result < 0) {
    LOG(ERROR) << "failed to refresh netlink cache: " << refill_result;
    return Network::State::kError;
  }
  std::unique_ptr<rtnl_link, Deleter> nl_link{
      rtnl_link_get(nl_cache_.get(), if_index)};
  if (!nl_link) {
    LOG(ERROR) << "failed to get interface 0";
    return Network::State::kError;
  }

  int state = rtnl_link_get_operstate(nl_link.get());
  switch (state) {
    case IF_OPER_DOWN:
    case IF_OPER_LOWERLAYERDOWN:
      return Network::State::kOffline;
    case IF_OPER_DORMANT:
      return Network::State::kConnecting;
    case IF_OPER_UP:
      return Network::State::kOnline;
    case IF_OPER_TESTING:
    case IF_OPER_NOTPRESENT:
    case IF_OPER_UNKNOWN:
    default:
      LOG(ERROR) << "unknown interface state: " << state;
      return Network::State::kError;
  }
}

weave::provider::Network::State NetlinkNetworkImpl::GetConnectionState() const {
  return network_state_;
}

void NetlinkNetworkImpl::OpenSslSocket(
    const std::string& host,
    uint16_t port,
    const OpenSslSocketSuccessCallback& success_callback,
    const ErrorCallback& error_callback) {
  // Connect to SSL port instead of upgrading to TLS.
  std::unique_ptr<SSLStream> tls_stream{new SSLStream{task_runner_}};

  if (tls_stream->Init(host, port)) {
    task_runner_->PostDelayedTask(
        FROM_HERE, base::Bind(success_callback, base::Passed(&tls_stream)), {});
  } else {
    ErrorPtr error;
    Error::AddTo(&error, FROM_HERE, "tls", "tls_init_failed",
                 "Failed to initialize TLS stream.");
    task_runner_->PostDelayedTask(
        FROM_HERE, base::Bind(error_callback, base::Passed(&error)), {});
  }
}

}  // namespace examples
}  // namespace weave
