// Copyright 2018 The Chromium 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 "osp/impl/service_listener_impl.h"

#include <algorithm>

#include "platform/base/error.h"
#include "util/osp_logging.h"

namespace openscreen {
namespace osp {
namespace {

bool IsTransitionValid(ServiceListener::State from, ServiceListener::State to) {
  switch (from) {
    case ServiceListener::State::kStopped:
      return to == ServiceListener::State::kStarting ||
             to == ServiceListener::State::kStopping;
    case ServiceListener::State::kStarting:
      return to == ServiceListener::State::kRunning ||
             to == ServiceListener::State::kStopping ||
             to == ServiceListener::State::kSuspended;
    case ServiceListener::State::kRunning:
      return to == ServiceListener::State::kSuspended ||
             to == ServiceListener::State::kSearching ||
             to == ServiceListener::State::kStopping;
    case ServiceListener::State::kStopping:
      return to == ServiceListener::State::kStopped;
    case ServiceListener::State::kSearching:
      return to == ServiceListener::State::kRunning ||
             to == ServiceListener::State::kSuspended ||
             to == ServiceListener::State::kStopping;
    case ServiceListener::State::kSuspended:
      return to == ServiceListener::State::kRunning ||
             to == ServiceListener::State::kSearching ||
             to == ServiceListener::State::kStopping;
    default:
      OSP_DCHECK(false) << "unknown ServiceListener::State value: "
                        << static_cast<int>(from);
      break;
  }
  return false;
}

}  // namespace

ServiceListenerImpl::Delegate::Delegate() = default;
ServiceListenerImpl::Delegate::~Delegate() = default;

void ServiceListenerImpl::Delegate::SetListenerImpl(
    ServiceListenerImpl* listener) {
  OSP_DCHECK(!listener_);
  listener_ = listener;
}

ServiceListenerImpl::ServiceListenerImpl(Delegate* delegate)
    : delegate_(delegate) {
  delegate_->SetListenerImpl(this);
}

ServiceListenerImpl::~ServiceListenerImpl() = default;

void ServiceListenerImpl::OnReceiverAdded(const ServiceInfo& info) {
  receiver_list_.OnReceiverAdded(info);
  for (auto* observer : observers_) {
    observer->OnReceiverAdded(info);
  }
}

void ServiceListenerImpl::OnReceiverChanged(const ServiceInfo& info) {
  const Error changed_error = receiver_list_.OnReceiverChanged(info);
  if (changed_error.ok()) {
    for (auto* observer : observers_) {
      observer->OnReceiverChanged(info);
    }
  }
}

void ServiceListenerImpl::OnReceiverRemoved(const ServiceInfo& info) {
  const Error removed_error = receiver_list_.OnReceiverRemoved(info);
  if (removed_error.ok()) {
    for (auto* observer : observers_) {
      observer->OnReceiverRemoved(info);
    }
  }
}

void ServiceListenerImpl::OnAllReceiversRemoved() {
  const Error removed_all_error = receiver_list_.OnAllReceiversRemoved();
  if (removed_all_error.ok()) {
    for (auto* observer : observers_) {
      observer->OnAllReceiversRemoved();
    }
  }
}

void ServiceListenerImpl::OnError(ServiceListenerError error) {
  last_error_ = error;
  for (auto* observer : observers_) {
    observer->OnError(error);
  }
}

bool ServiceListenerImpl::Start() {
  if (state_ != State::kStopped)
    return false;
  state_ = State::kStarting;
  delegate_->StartListener();
  return true;
}

bool ServiceListenerImpl::StartAndSuspend() {
  if (state_ != State::kStopped)
    return false;
  state_ = State::kStarting;
  delegate_->StartAndSuspendListener();
  return true;
}

bool ServiceListenerImpl::Stop() {
  if (state_ == State::kStopped || state_ == State::kStopping)
    return false;

  state_ = State::kStopping;
  delegate_->StopListener();
  return true;
}

bool ServiceListenerImpl::Suspend() {
  if (state_ != State::kRunning && state_ != State::kSearching &&
      state_ != State::kStarting) {
    return false;
  }
  delegate_->SuspendListener();
  return true;
}

bool ServiceListenerImpl::Resume() {
  if (state_ != State::kSuspended && state_ != State::kSearching)
    return false;

  delegate_->ResumeListener();
  return true;
}

bool ServiceListenerImpl::SearchNow() {
  if (state_ != State::kRunning && state_ != State::kSuspended)
    return false;

  delegate_->SearchNow(state_);
  return true;
}

void ServiceListenerImpl::AddObserver(Observer* observer) {
  OSP_DCHECK(observer);
  observers_.push_back(observer);
}

void ServiceListenerImpl::RemoveObserver(Observer* observer) {
  // TODO(btolsch): Consider writing an ObserverList in base/ for things like
  // CHECK()ing that the list is empty on destruction.
  observers_.erase(std::remove(observers_.begin(), observers_.end(), observer),
                   observers_.end());
}

const std::vector<ServiceInfo>& ServiceListenerImpl::GetReceivers() const {
  return receiver_list_.receivers();
}

void ServiceListenerImpl::SetState(State state) {
  OSP_DCHECK(IsTransitionValid(state_, state));
  state_ = state;
  if (!observers_.empty()) {
    MaybeNotifyObservers();
  }
}

void ServiceListenerImpl::MaybeNotifyObservers() {
  OSP_DCHECK(!observers_.empty());
  switch (state_) {
    case State::kRunning:
      for (auto* observer : observers_) {
        observer->OnStarted();
      }
      break;
    case State::kStopped:
      for (auto* observer : observers_) {
        observer->OnStopped();
      }
      break;
    case State::kSuspended:
      for (auto* observer : observers_) {
        observer->OnSuspended();
      }
      break;
    case State::kSearching:
      for (auto* observer : observers_) {
        observer->OnSearching();
      }
      break;
    default:
      break;
  }
}

}  // namespace osp
}  // namespace openscreen
