// 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(
      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(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(kProviderHostProperty, "");
}

}  // namespace shill
