// Copyright (c) 2012 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 "shill/shims/ppp.h"

#include <arpa/inet.h>
#include <netinet/in.h>

extern "C" {
#include <pppd/fsm.h>
#include <pppd/ipcp.h>
}

#include <base/at_exit.h>
#include <base/command_line.h>
#include <base/logging.h>
#include <chromeos/syslog_logging.h>
#include <dbus-c++/eventloop-integration.h>

#include "shill/l2tp_ipsec_driver.h"
#include "shill/rpc_task.h"
#include "shill/shims/environment.h"
#include "shill/shims/task_proxy.h"

using std::map;
using std::string;

namespace shill {

namespace shims {

base::AtExitManager *PPP::exit_manager_ = NULL;

PPP::PPP() {}

PPP::~PPP() {}

void PPP::Start() {
  if (exit_manager_) {
    return;
  }
  exit_manager_ = new base::AtExitManager();
  CommandLine::Init(0, NULL);
  chromeos::InitLog(chromeos::kLogToSyslog | chromeos::kLogHeader);
  LOG(INFO) << "PPP started.";
}

void PPP::Stop() {
  LOG(INFO) << "PPP stopped.";
  delete exit_manager_;
  exit_manager_ = NULL;
}

bool PPP::GetSecret(string *username, string *password) {
  LOG(INFO) << __func__;
  if (!CreateProxy()) {
    return false;
  }
  bool success = proxy_->GetSecret(username, password);
  DestroyProxy();
  return success;
}

void PPP::OnConnect(const string &ifname) {
  LOG(INFO) << __func__ << "(" << ifname << ")";
  if (!ipcp_gotoptions[0].ouraddr) {
    LOG(ERROR) << "ouraddr not set.";
    return;
  }
  map<string, string> dict;
  dict[kL2TPIPSecInterfaceName] = ifname;
  dict[kL2TPIPSecInternalIP4Address] =
      ConvertIPToText(&ipcp_gotoptions[0].ouraddr);
  dict[kL2TPIPSecExternalIP4Address] =
      ConvertIPToText(&ipcp_hisoptions[0].hisaddr);
  if (ipcp_gotoptions[0].default_route) {
    dict[kL2TPIPSecGatewayAddress] = dict[kL2TPIPSecExternalIP4Address];
  }
  if (ipcp_gotoptions[0].dnsaddr[0]) {
    dict[kL2TPIPSecDNS1] = ConvertIPToText(&ipcp_gotoptions[0].dnsaddr[0]);
  }
  if (ipcp_gotoptions[0].dnsaddr[1]) {
    dict[kL2TPIPSecDNS2] = ConvertIPToText(&ipcp_gotoptions[0].dnsaddr[1]);
  }
  string lns_address;
  if (Environment::GetInstance()->GetVariable("LNS_ADDRESS", &lns_address)) {
    dict[kL2TPIPSecLNSAddress] = lns_address;
  }
  if (CreateProxy()) {
    proxy_->Notify(kL2TPIPSecReasonConnect, dict);
    DestroyProxy();
  }
}

void PPP::OnDisconnect() {
  LOG(INFO) << __func__;
  if (CreateProxy()) {
    map<string, string> dict;
    proxy_->Notify(kL2TPIPSecReasonDisconnect, dict);
    DestroyProxy();
  }
}

bool PPP::CreateProxy() {
  Environment *environment = Environment::GetInstance();
  string service, path;
  if (!environment->GetVariable(shill::kRPCTaskServiceVariable, &service) ||
      !environment->GetVariable(shill::kRPCTaskPathVariable, &path)) {
    LOG(ERROR) << "Environment variables not available.";
    return false;
  }

  dispatcher_.reset(new DBus::BusDispatcher());
  DBus::default_dispatcher = dispatcher_.get();
  connection_.reset(new DBus::Connection(DBus::Connection::SystemBus()));
  proxy_.reset(new TaskProxy(connection_.get(), path, service));
  LOG(INFO) << "Task proxy created: " << service << " - " << path;
  return true;
}

void PPP::DestroyProxy() {
  proxy_.reset();
  connection_.reset();
  DBus::default_dispatcher = NULL;
  dispatcher_.reset();
  LOG(INFO) << "Task proxy destroyed.";
}

// static
string PPP::ConvertIPToText(const void *addr) {
  char text[INET_ADDRSTRLEN];
  inet_ntop(AF_INET, addr, text, INET_ADDRSTRLEN);
  return text;
}

}  // namespace shims

}  // namespace shill
