// 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 <base/string_util.h>
#include <chromeos/dbus/service_constants.h>

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

using std::string;

namespace shill {

VPNDriver::VPNDriver(Manager *manager,
                     const Property *properties,
                     size_t property_count)
    : manager_(manager),
      properties_(properties),
      property_count_(property_count) {}

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;
    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;
    string value;
    if (!credential || save_credentials) {
      value = args_.LookupString(property, "");
    }
    if (value.empty()) {
      storage->DeleteKey(storage_id, property);
    } else 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++) {
    store->RegisterDerivedString(
        properties_[i].property,
        StringAccessor(
            new CustomMappedAccessor<VPNDriver, string, size_t>(
                this,
                &VPNDriver::ClearMappedProperty,
                &VPNDriver::GetMappedProperty,
                &VPNDriver::SetMappedProperty,
                i)));
  }

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

void VPNDriver::ClearMappedProperty(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");
  }
}

string VPNDriver::GetMappedProperty(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();
}

void VPNDriver::SetMappedProperty(
    const size_t &index, const string &value, Error *error) {
  CHECK(index < property_count_);
  args_.SetString(properties_[index].property, value);
}

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 value = args_.LookupString(properties_[i].property, "");
    if (!value.empty()) {
      // Chomp off leading "Provider." from properties that have this prefix.
      string prop = properties_[i].property;
      if (StartsWithASCII(prop, provider_prefix, false)) {
        prop = prop.substr(provider_prefix.length());
      }
      provider_properties.SetString(prop, value);
    }
  }

  return provider_properties;
}

}  // namespace shill
