// 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_t 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, const char *reason) {
  SLOG(WiMax, 2) << __func__;
  if (!device_) {
    Error::PopulateAndLog(
        error, Error::kNotConnected, "Not connected.");
    return;
  }
  Service::Disconnect(error, reason);
  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();
  SetHasEverConnected(false);
  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_t 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
