// Copyright 2018 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/cellular/pending_activation_store.h"

#include <utility>

#include "shill/logging.h"
#include "shill/store_interface.h"

using base::FilePath;
using std::string;

namespace shill {

namespace Logging {
static auto kModuleLogScope = ScopeLogger::kCellular;
static string ObjectID(const PendingActivationStore* p) {
  return "(pending_activation_store)";
}
}  // namespace Logging

const char PendingActivationStore::kIccidGroupId[] = "iccid_list";
const char PendingActivationStore::kMeidGroupId[] = "meid_list";
// We're keeping the old file name here for backwards compatibility.
const char PendingActivationStore::kStorageFileName[] =
    "activating_iccid_store.profile";

PendingActivationStore::PendingActivationStore() = default;

PendingActivationStore::~PendingActivationStore() {
  if (storage_)
    storage_->Flush();  // Make certain that everything is persisted.
}

namespace {

string StateToString(PendingActivationStore::State state) {
  switch (state) {
    case PendingActivationStore::kStateUnknown:
      return "Unknown";
    case PendingActivationStore::kStatePending:
      return "Pending";
    case PendingActivationStore::kStateActivated:
      return "Activated";
    default:
      return "Invalid";
  }
}

string FormattedIdentifier(PendingActivationStore::IdentifierType type,
                           const string& identifier) {
  string label;
  switch (type) {
    case PendingActivationStore::kIdentifierICCID:
      label = "ICCID";
      break;
    case PendingActivationStore::kIdentifierMEID:
      label = "MEID";
      break;
    default:
      NOTREACHED();
  }
  return "[" + label + "=" + identifier + "]";
}

}  // namespace

// static
string PendingActivationStore::IdentifierTypeToGroupId(IdentifierType type) {
  switch (type) {
    case kIdentifierICCID:
      return kIccidGroupId;
    case kIdentifierMEID:
      return kMeidGroupId;
    default:
      SLOG(Cellular, nullptr, 2) << "Incorrect identifier type: " << type;
      return "";
  }
}

bool PendingActivationStore::InitStorage(const FilePath& storage_path) {
  // Close the current file.
  if (storage_) {
    storage_->Flush();
    storage_.reset();  // KeyFileStore closes the file in its destructor.
  }
  if (storage_path.empty()) {
    LOG(ERROR) << "Empty storage directory path provided.";
    return false;
  }
  FilePath path = storage_path.Append(kStorageFileName);
  std::unique_ptr<StoreInterface> storage = CreateStore(path);
  bool already_exists = !storage->IsEmpty();
  if (!storage->Open()) {
    LOG(ERROR) << "Failed to open file at '" << path.value() << "'";
    if (already_exists)
      storage->MarkAsCorrupted();
    return false;
  }
  if (!already_exists)
    storage->SetHeader("Identifiers pending cellular activation.");
  storage_ = std::move(storage);
  return true;
}

PendingActivationStore::State PendingActivationStore::GetActivationState(
    IdentifierType type, const string& identifier) const {
  string formatted_identifier = FormattedIdentifier(type, identifier);
  SLOG(this, 2) << __func__ << ": " << formatted_identifier;
  if (!storage_) {
    LOG(ERROR) << "Underlying storage not initialized.";
    return kStateUnknown;
  }
  int state = 0;
  if (!storage_->GetInt(IdentifierTypeToGroupId(type), identifier, &state)) {
    SLOG(this, 2) << "No entry exists for " << formatted_identifier;
    return kStateUnknown;
  }
  if (state <= 0 || state >= kStateMax) {
    SLOG(this, 2) << "State value read for " << formatted_identifier
                  << " is invalid.";
    return kStateUnknown;
  }
  return static_cast<State>(state);
}

bool PendingActivationStore::SetActivationState(IdentifierType type,
                                                const string& identifier,
                                                State state) {
  SLOG(this, 2) << __func__ << ": State=" << StateToString(state) << ", "
                << FormattedIdentifier(type, identifier);
  if (!storage_) {
    LOG(ERROR) << "Underlying storage not initialized.";
    return false;
  }
  if (state == kStateUnknown) {
    SLOG(this, 2) << "kStateUnknown cannot be used as a value.";
    return false;
  }
  if (state < 0 || state >= kStateMax) {
    SLOG(this, 2) << "Cannot set state to \"" << StateToString(state) << "\"";
    return false;
  }
  if (!storage_->SetInt(IdentifierTypeToGroupId(type), identifier,
                        static_cast<int>(state))) {
    SLOG(this, 2) << "Failed to store the given identifier and state "
                  << "values.";
    return false;
  }
  return storage_->Flush();
}

bool PendingActivationStore::RemoveEntry(IdentifierType type,
                                         const std::string& identifier) {
  SLOG(this, 2) << __func__ << ": " << FormattedIdentifier(type, identifier);
  if (!storage_) {
    LOG(ERROR) << "Underlying storage not initialized.";
    return false;
  }
  if (!storage_->DeleteKey(IdentifierTypeToGroupId(type), identifier)) {
    SLOG(this, 2) << "Failed to remove the given identifier.";
    return false;
  }
  return storage_->Flush();
}

}  // namespace shill
