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

#include <algorithm>

#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <chromeos/dbus/service_constants.h>

#include "shill/dbus_adaptor.h"
#include "shill/eap_credentials.h"
#include "shill/key_value_store.h"
#include "shill/logging.h"
#include "shill/manager.h"
#include "shill/store_interface.h"
#include "shill/technology.h"
#include "shill/wimax.h"

using std::replace_if;
using std::string;

namespace shill {

const char WiMaxService::kStorageNetworkId[] = "NetworkId";
const char WiMaxService::kNetworkIdProperty[] = "NetworkId";

WiMaxService::WiMaxService(ControlInterface *control,
                           EventDispatcher *dispatcher,
                           Metrics *metrics,
                           Manager *manager)
    : Service(control, dispatcher, metrics, manager, Technology::kWiMax),
      need_passphrase_(true),
      is_default_(false) {
  PropertyStore *store = this->mutable_store();
  // TODO(benchan): Support networks that require no user credentials or
  // implicitly defined credentials.
  store->RegisterBool(kPassphraseRequiredProperty, &need_passphrase_);
  store->RegisterConstString(kNetworkIdProperty, &network_id_);

  SetEapCredentials(new EapCredentials());

  IgnoreParameterForConfigure(kNetworkIdProperty);

  // Initialize a default storage identifier based on the service's unique
  // name. The identifier most likely needs to be reinitialized by the caller
  // when its components have been set.
  InitStorageIdentifier();

  // Now that |this| is a fully constructed WiMaxService, synchronize observers
  // with our current state, and emit the appropriate change notifications.
  // (Initial observer state may have been set in our base class.)
  NotifyPropertyChanges();
}

WiMaxService::~WiMaxService() {}

void WiMaxService::GetConnectParameters(KeyValueStore *parameters) const {
  CHECK(parameters);
  eap()->PopulateWiMaxProperties(parameters);
}

RpcIdentifier WiMaxService::GetNetworkObjectPath() const {
  CHECK(proxy_.get());
  return proxy_->path();
}

void WiMaxService::Stop() {
  if (!IsStarted()) {
    return;
  }
  LOG(INFO) << "Stopping WiMAX service: " << GetStorageIdentifier();
  proxy_.reset();
  SetStrength(0);
  if (device_) {
    device_->OnServiceStopped(this);
    SetDevice(NULL);
  }
  UpdateConnectable();
  NotifyPropertyChanges();
}

bool WiMaxService::Start(WiMaxNetworkProxyInterface *proxy) {
  SLOG(WiMax, 2) << __func__;
  CHECK(proxy);
  scoped_ptr<WiMaxNetworkProxyInterface> local_proxy(proxy);
  if (IsStarted()) {
    return true;
  }
  if (friendly_name().empty()) {
    LOG(ERROR) << "Empty service name.";
    return false;
  }
  Error error;
  network_name_ = proxy->Name(&error);
  if (error.IsFailure()) {
    return false;
  }
  uint32 identifier = proxy->Identifier(&error);
  if (error.IsFailure()) {
    return false;
  }
  WiMaxNetworkId id = ConvertIdentifierToNetworkId(identifier);
  if (id != network_id_) {
    LOG(ERROR) << "Network identifiers don't match: "
               << id << " != " << network_id_;
    return false;
  }
  int signal_strength = proxy->SignalStrength(&error);
  if (error.IsFailure()) {
    return false;
  }
  SetStrength(signal_strength);
  proxy->set_signal_strength_changed_callback(
      Bind(&WiMaxService::OnSignalStrengthChanged, Unretained(this)));
  proxy_.reset(local_proxy.release());
  UpdateConnectable();
  NotifyPropertyChanges();
  LOG(INFO) << "WiMAX service started: " << GetStorageIdentifier();
  return true;
}

bool WiMaxService::IsStarted() const {
  return proxy_.get();
}

void WiMaxService::Connect(Error *error, const char *reason) {
  SLOG(WiMax, 2) << __func__;
  if (device_) {
    // TODO(benchan): Populate error again after changing the way that
    // Chrome handles Error::kAlreadyConnected situation.
    LOG(WARNING) << "Service " << GetStorageIdentifier()
                 << " is already being connected or already connected.";
    return;
  }
  if (!connectable()) {
    LOG(ERROR) << "Can't connect. Service " << GetStorageIdentifier()
               << " is not connectable.";
    Error::PopulateAndLog(error, Error::kOperationFailed,
                          Error::GetDefaultMessage(Error::kOperationFailed));
    return;
  }
  WiMaxRefPtr carrier = manager()->wimax_provider()->SelectCarrier(this);
  if (!carrier) {
    Error::PopulateAndLog(
        error, Error::kNoCarrier, "No suitable WiMAX device available.");
    return;
  }
  Service::Connect(error, reason);
  carrier->ConnectTo(this, error);
  if (error->IsSuccess()) {
    // Associate with the carrier device if the connection process has been
    // initiated successfully.
    SetDevice(carrier);
  }
}

void WiMaxService::Disconnect(Error *error) {
  SLOG(WiMax, 2) << __func__;
  if (!device_) {
    Error::PopulateAndLog(
        error, Error::kNotConnected, "Not connected.");
    return;
  }
  Service::Disconnect(error);
  device_->DisconnectFrom(this, error);
  SetDevice(NULL);
}

string WiMaxService::GetStorageIdentifier() const {
  return storage_id_;
}

string WiMaxService::GetDeviceRpcId(Error *error) const {
  if (!device_) {
    error->Populate(Error::kNotFound, "Not associated with a device");
    return DBusAdaptor::kNullPath;
  }
  return device_->GetRpcIdentifier();
}

bool WiMaxService::IsAutoConnectable(const char **reason) const {
  if (!Service::IsAutoConnectable(reason)) {
    return false;
  }
  WiMaxRefPtr device = manager()->wimax_provider()->SelectCarrier(this);
  DCHECK(device);
  if (!device->IsIdle()) {
    *reason = kAutoConnBusy;
    return false;
  }
  return true;
}

bool WiMaxService::Is8021x() const {
  return true;
}

bool WiMaxService::IsVisible() const {
  // WiMAX services should be displayed only if they are in range (i.e.
  // a corresponding network is exposed by WiMAX manager).
  return IsStarted();
}

void WiMaxService::OnEapCredentialsChanged() {
  need_passphrase_ = !eap()->IsConnectableUsingPassphrase();
  UpdateConnectable();
}

void WiMaxService::UpdateConnectable() {
  SLOG(WiMax, 2) << __func__ << "(started: " << IsStarted()
                 << ", need passphrase: " << need_passphrase_ << ")";
  SetConnectableFull(IsStarted() && !need_passphrase_);
}

void WiMaxService::OnSignalStrengthChanged(int strength) {
  SLOG(WiMax, 2) << __func__ << "(" << strength << ")";
  SetStrength(strength);
}

void WiMaxService::SetDevice(WiMaxRefPtr new_device) {
  if (device_ == new_device)
    return;
  if (new_device) {
    adaptor()->EmitRpcIdentifierChanged(kDeviceProperty,
                                        new_device->GetRpcIdentifier());
  } else {
    adaptor()->EmitRpcIdentifierChanged(kDeviceProperty,
                                        DBusAdaptor::kNullPath);
  }
  device_ = new_device;
}

bool WiMaxService::Save(StoreInterface *storage) {
  SLOG(WiMax, 2) << __func__;
  if (!Service::Save(storage)) {
    return false;
  }
  const string id = GetStorageIdentifier();
  storage->SetString(id, kStorageNetworkId, network_id_);

  return true;
}

bool WiMaxService::Unload() {
  SLOG(WiMax, 2) << __func__;
  // The base method also disconnects the service.
  Service::Unload();
  ClearPassphrase();
  // Notify the WiMAX provider that this service has been unloaded. If the
  // provider releases ownership of this service, it needs to be deregistered.
  return manager()->wimax_provider()->OnServiceUnloaded(this);
}

void WiMaxService::SetState(ConnectState state) {
  Service::SetState(state);
  if (!IsConnecting() && !IsConnected()) {
    // Disassociate from any carrier device if it's not connected anymore.
    SetDevice(NULL);
  }
}

// static
WiMaxNetworkId WiMaxService::ConvertIdentifierToNetworkId(uint32 identifier) {
  return base::StringPrintf("%08x", identifier);
}

void WiMaxService::InitStorageIdentifier() {
  storage_id_ = CreateStorageIdentifier(network_id_, friendly_name());
}

// static
string WiMaxService::CreateStorageIdentifier(const WiMaxNetworkId &id,
                                             const string &name) {
  string storage_id =
      base::StringPrintf("%s_%s_%s",
                         kTypeWimax, name.c_str(), id.c_str());
  StringToLowerASCII(&storage_id);
  replace_if(storage_id.begin(), storage_id.end(), &Service::IllegalChar, '_');
  return storage_id;
}

void WiMaxService::ClearPassphrase() {
  SLOG(WiMax, 2) << __func__;
  mutable_eap()->set_password("");
  OnEapCredentialsChanged();
}

}  // namespace shill
