// Copyright 2019 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/ethernet/ethernet_provider.h"

#include <string>

#include "shill/ethernet/ethernet_service.h"
#include "shill/ethernet/ethernet_temporary_service.h"
#include "shill/logging.h"
#include "shill/manager.h"
#include "shill/store_interface.h"

#include <base/check.h>
#include <base/check_op.h>

using std::string;

namespace shill {

namespace Logging {
static auto kModuleLogScope = ScopeLogger::kEthernet;
static string ObjectID(const EthernetProvider* e) {
  return "(ethernet_provider)";
}
}  // namespace Logging

EthernetProvider::EthernetProvider(Manager* manager) : manager_(manager) {}

EthernetProvider::~EthernetProvider() = default;

void EthernetProvider::CreateServicesFromProfile(const ProfileRefPtr& profile) {
  SLOG(this, 2) << __func__;
  // Since the EthernetProvider's service is created during Start(),
  // there is no need to do anything in this method.
}

ServiceRefPtr EthernetProvider::FindSimilarService(const KeyValueStore& args,
                                                   Error* error) const {
  CHECK_EQ(kTypeEthernet, args.Lookup<string>(kTypeProperty, ""))
      << "Service type must be Ethernet!";
  ServiceRefPtr service = manager_->GetFirstEthernetService();
  if (service) {
    return service;
  }
  return service_;
}

ServiceRefPtr EthernetProvider::GetService(const KeyValueStore& args,
                                           Error* error) {
  SLOG(this, 2) << __func__;
  return FindSimilarService(args, error);
}

ServiceRefPtr EthernetProvider::CreateTemporaryService(
    const KeyValueStore& args, Error* error) {
  SLOG(this, 2) << __func__;
  return new EthernetTemporaryService(
      manager_, EthernetService::kDefaultEthernetDeviceIdentifier);
}

ServiceRefPtr EthernetProvider::CreateTemporaryServiceFromProfile(
    const ProfileRefPtr& profile, const std::string& entry_name, Error* error) {
  SLOG(this, 2) << __func__;
  return new EthernetTemporaryService(manager_, entry_name);
}

EthernetServiceRefPtr EthernetProvider::CreateService(
    base::WeakPtr<Ethernet> ethernet) {
  SLOG(this, 2) << __func__;
  if (!service_->HasEthernet()) {
    service_->SetEthernet(ethernet);
    return service_;
  }
  return new EthernetService(manager_, EthernetService::Properties(ethernet));
}

void EthernetProvider::RegisterService(EthernetServiceRefPtr service) {
  SLOG(this, 2) << __func__;
  CHECK(service);
  // Add the service to the services_ list and register it with the Manager.
  // A service is registered with the Manager if and only if it is also
  // registered with the EthernetProvider.
  if (base::Contains(services_, service)) {
    LOG(INFO) << "Reusing existing Ethernet service.";
    return;
  }
  services_.push_back(service);
  manager_->RegisterService(service);
}

void EthernetProvider::DeregisterService(EthernetServiceRefPtr service) {
  SLOG(this, 2) << __func__;
  CHECK(service);
  // Remove the service from the services_ list if it is not the only remaining
  // service. Otherwise, turn it into the ethernet_any service. A service is
  // deregistered with the Manager if and only if it is also deregistered with
  // the EthernetProvider.
  CHECK(base::Contains(services_, service))
      << "De-registering an unregistered service";
  if (services_.size() == 1 && service->HasEthernet()) {
    service->ResetEthernet();
    return;
  }
  base::Erase(services_, service);
  manager_->DeregisterService(service);
}

EthernetServiceRefPtr EthernetProvider::FindEthernetServiceForService(
    ServiceRefPtr service) const {
  CHECK(service);
  for (const auto& s : services_) {
    if (s->serial_number() == service->serial_number()) {
      return s;
    }
  }
  return nullptr;
}

bool EthernetProvider::LoadGenericEthernetService() {
  SLOG(this, 2) << __func__;
  return manager_->ActiveProfile()->LoadService(service_);
}

void EthernetProvider::RefreshGenericEthernetService() {
  // Make sure that the first Ethernet service is the generic Ethernet service.
  // This is to ensure that the preferred/default Ethernet service is the one
  // being configured.
  ServiceRefPtr first_ethernet_service = manager_->GetFirstEthernetService();
  CHECK(first_ethernet_service);
  if (first_ethernet_service == service_) {
    return;
  }

  // The first Ethernet service has changed. Remove the ethernet_any storage ID
  // from the old ethernet_any service and configure it according to its new
  // storage ID (MAC address of the associated device). If it has no associated
  // Device, release the service as there should no longer be any other
  // references to it.
  service_->ResetStorageIdentifier();
  if (base::Contains(services_, service_)) {
    if (service_->HasEthernet()) {
      manager_->MatchProfileWithService(service_);
    } else {
      // There's no associated Device and it's no longer the ethernet_any
      // service. Get rid of this service completely.
      DeregisterService(service_);
    }
  }

  // Set the storage ID of the new first Ethernet service to be ethernet_any and
  // configure it accordingly.
  service_ = FindEthernetServiceForService(first_ethernet_service);
  service_->SetStorageIdentifier(
      EthernetService::kDefaultEthernetDeviceIdentifier);
  manager_->MatchProfileWithService(service_);
}

void EthernetProvider::Start() {
  SLOG(this, 2) << __func__;
  // Create a generic Ethernet service with storage ID "ethernet_any". This will
  // be used to store configurations if any are pushed down from Chrome before
  // any Ethernet devices are initialized. This will also be used to persist
  // static IP configurations across Ethernet services.
  if (!service_) {
    service_ = new EthernetService(
        manager_, EthernetService::Properties(
                      EthernetService::kDefaultEthernetDeviceIdentifier));
  }
  RegisterService(service_);
}

void EthernetProvider::Stop() {
  SLOG(this, 2) << __func__;
  while (!services_.empty()) {
    EthernetServiceRefPtr service = services_.back();
    DeregisterService(service);
  }
  // Do not destroy the service, since devices may or may not have been
  // removed as the provider is stopped, and we'd like them to continue
  // to refer to the same service on restart.
}

}  // namespace shill
