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

#include <string>
#include <vector>

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

#include "shill/connection.h"
#include "shill/event_dispatcher.h"
#include "shill/logging.h"
#include "shill/manager.h"
#include "shill/property_accessor.h"
#include "shill/property_store.h"
#include "shill/store_interface.h"

using std::string;
using std::vector;

namespace shill {

// static
const int VPNDriver::kDefaultConnectTimeoutSeconds = 60;

VPNDriver::VPNDriver(EventDispatcher *dispatcher,
                     Manager *manager,
                     const Property *properties,
                     size_t property_count)
    : weak_ptr_factory_(this),
      dispatcher_(dispatcher),
      manager_(manager),
      properties_(properties),
      property_count_(property_count),
      connect_timeout_seconds_(0) {}

VPNDriver::~VPNDriver() {}

bool VPNDriver::Load(StoreInterface *storage, const string &storage_id) {
  SLOG(VPN, 2) << __func__;
  for (size_t i = 0; i < property_count_; i++) {
    if ((properties_[i].flags & Property::kEphemeral)) {
      continue;
    }
    const string property = properties_[i].property;
    if (properties_[i].flags & Property::kArray) {
      CHECK(!(properties_[i].flags & Property::kCredential))
          << "Property cannot be both an array and a credential";
      vector<string> value;
      if (storage->GetStringList(storage_id, property, &value)) {
        args_.SetStrings(property, value);
      } else {
        args_.RemoveStrings(property);
      }
    } else {
      string value;
      bool loaded = (properties_[i].flags & Property::kCredential) ?
          storage->GetCryptedString(storage_id, property, &value) :
          storage->GetString(storage_id, property, &value);
      if (loaded) {
        args_.SetString(property, value);
      } else {
        args_.RemoveString(property);
      }
    }
  }
  return true;
}

bool VPNDriver::Save(StoreInterface *storage,
                     const string &storage_id,
                     bool save_credentials) {
  SLOG(VPN, 2) << __func__;
  for (size_t i = 0; i < property_count_; i++) {
    if ((properties_[i].flags & Property::kEphemeral)) {
      continue;
    }
    bool credential = (properties_[i].flags & Property::kCredential);
    const string property = properties_[i].property;
    if (properties_[i].flags & Property::kArray) {
      CHECK(!credential)
          << "Property cannot be both an array and a credential";
      if (!args_.ContainsStrings(property)) {
        storage->DeleteKey(storage_id, property);
        continue;
      }
      Strings value = args_.GetStrings(property);
      storage->SetStringList(storage_id, property, value);
    } else {
      if (!args_.ContainsString(property) ||
          (credential && !save_credentials)) {
        storage->DeleteKey(storage_id, property);
        continue;
      }
      string value = args_.GetString(property);
      if (credential) {
        storage->SetCryptedString(storage_id, property, value);
      } else {
        storage->SetString(storage_id, property, value);
      }
    }
  }
  return true;
}

void VPNDriver::UnloadCredentials() {
  SLOG(VPN, 2) << __func__;
  for (size_t i = 0; i < property_count_; i++) {
    if ((properties_[i].flags &
         (Property::kEphemeral | Property::kCredential))) {
      args_.RemoveString(properties_[i].property);
    }
  }
}

void VPNDriver::InitPropertyStore(PropertyStore *store) {
  SLOG(VPN, 2) << __func__;
  for (size_t i = 0; i < property_count_; i++) {
    if (properties_[i].flags & Property::kArray) {
      store->RegisterDerivedStrings(
          properties_[i].property,
          StringsAccessor(
              new CustomMappedAccessor<VPNDriver, Strings, size_t>(
                  this,
                  &VPNDriver::ClearMappedStringsProperty,
                  &VPNDriver::GetMappedStringsProperty,
                  &VPNDriver::SetMappedStringsProperty,
                  i)));
    } else {
      store->RegisterDerivedString(
          properties_[i].property,
          StringAccessor(
              new CustomMappedAccessor<VPNDriver, string, size_t>(
                  this,
                  &VPNDriver::ClearMappedStringProperty,
                  &VPNDriver::GetMappedStringProperty,
                  &VPNDriver::SetMappedStringProperty,
                  i)));
    }
  }

  store->RegisterDerivedKeyValueStore(
      flimflam::kProviderProperty,
      KeyValueStoreAccessor(
          new CustomAccessor<VPNDriver, KeyValueStore>(
              this, &VPNDriver::GetProvider, NULL)));
}

void VPNDriver::ClearMappedStringProperty(const size_t &index, Error *error) {
  CHECK(index < property_count_);
  if (args_.ContainsString(properties_[index].property)) {
    args_.RemoveString(properties_[index].property);
  } else {
    error->Populate(Error::kNotFound, "Property is not set");
  }
}

void VPNDriver::ClearMappedStringsProperty(const size_t &index, Error *error) {
  CHECK(index < property_count_);
  if (args_.ContainsStrings(properties_[index].property)) {
    args_.RemoveStrings(properties_[index].property);
  } else {
    error->Populate(Error::kNotFound, "Property is not set");
  }
}

string VPNDriver::GetMappedStringProperty(const size_t &index, Error *error) {
  // Provider properties are set via SetProperty calls to "Provider.XXX",
  // however, they are retrieved via a GetProperty call, which returns all
  // properties in a single "Provider" dict.  Therefore, none of the individual
  // properties in the kProperties are available for enumeration in
  // GetProperties.  Instead, they are retrieved via GetProvider below.
  error->Populate(Error::kInvalidArguments,
                  "Provider properties are not read back in this manner");
  return string();
}

Strings VPNDriver::GetMappedStringsProperty(const size_t &index, Error *error) {
  // Provider properties are set via SetProperty calls to "Provider.XXX",
  // however, they are retrieved via a GetProperty call, which returns all
  // properties in a single "Provider" dict.  Therefore, none of the individual
  // properties in the kProperties are available for enumeration in
  // GetProperties.  Instead, they are retrieved via GetProvider below.
  error->Populate(Error::kInvalidArguments,
                  "Provider properties are not read back in this manner");
  return Strings();
}

bool VPNDriver::SetMappedStringProperty(
    const size_t &index, const string &value, Error *error) {
  CHECK(index < property_count_);
  if (args_.ContainsString(properties_[index].property) &&
      args_.GetString(properties_[index].property) == value) {
    return false;
  }
  args_.SetString(properties_[index].property, value);
  return true;
}

bool VPNDriver::SetMappedStringsProperty(
    const size_t &index, const Strings &value, Error *error) {
  CHECK(index < property_count_);
  if (args_.ContainsStrings(properties_[index].property) &&
      args_.GetStrings(properties_[index].property) == value) {
    return false;
  }
  args_.SetStrings(properties_[index].property, value);
  return true;
}

KeyValueStore VPNDriver::GetProvider(Error *error) {
  SLOG(VPN, 2) << __func__;
  string provider_prefix = string(flimflam::kProviderProperty) + ".";
  KeyValueStore provider_properties;

  for (size_t i = 0; i < property_count_; i++) {
    if ((properties_[i].flags & Property::kWriteOnly)) {
      continue;
    }
    string prop = properties_[i].property;

    // Chomp off leading "Provider." from properties that have this prefix.
    string chopped_prop;
    if (StartsWithASCII(prop, provider_prefix, false)) {
      chopped_prop = prop.substr(provider_prefix.length());
    } else {
      chopped_prop = prop;
    }

    if (properties_[i].flags & Property::kArray) {
      if (!args_.ContainsStrings(prop)) {
        continue;
      }
      Strings value = args_.GetStrings(prop);
      provider_properties.SetStrings(chopped_prop, value);
    } else {
      if (!args_.ContainsString(prop)) {
        continue;
      }
      string value = args_.GetString(prop);
      provider_properties.SetString(chopped_prop, value);
    }
  }

  return provider_properties;
}

void VPNDriver::StartConnectTimeout(int timeout_seconds) {
  if (IsConnectTimeoutStarted()) {
    return;
  }
  LOG(INFO) << "Schedule VPN connect timeout: "
            << timeout_seconds << " seconds.";
  connect_timeout_seconds_ = timeout_seconds;
  connect_timeout_callback_.Reset(
      Bind(&VPNDriver::OnConnectTimeout, weak_ptr_factory_.GetWeakPtr()));
  dispatcher_->PostDelayedTask(
      connect_timeout_callback_.callback(), timeout_seconds * 1000);
}

void VPNDriver::StopConnectTimeout() {
  SLOG(VPN, 2) << __func__;
  connect_timeout_callback_.Cancel();
  connect_timeout_seconds_ = 0;
}

bool VPNDriver::IsConnectTimeoutStarted() const {
  return !connect_timeout_callback_.IsCancelled();
}

void VPNDriver::OnConnectTimeout() {
  LOG(INFO) << "VPN connect timeout.";
  StopConnectTimeout();
}

string VPNDriver::GetHost() const {
  return args_.LookupString(flimflam::kProviderHostProperty, "");
}

}  // namespace shill
