// Copyright (c) 2013 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 "chromeos/dbus/fake_cras_audio_client.h"

#include <utility>

namespace chromeos {

FakeCrasAudioClient::FakeCrasAudioClient()
    : active_input_node_id_(0),
      active_output_node_id_(0) {
}

FakeCrasAudioClient::~FakeCrasAudioClient() = default;

void FakeCrasAudioClient::Init(dbus::Bus* bus) {
  VLOG(1) << "FakeCrasAudioClient is created";

  // Fake audio output nodes.
  AudioNode output_1;
  output_1.is_input = false;
  output_1.id = 10001;
  output_1.stable_device_id_v1 = 10001;
  output_1.device_name = "Fake Speaker";
  output_1.type = "INTERNAL_SPEAKER";
  output_1.name = "Speaker";
  node_list_.push_back(output_1);

  AudioNode output_2;
  output_2.is_input = false;
  output_2.id = 10002;
  output_2.stable_device_id_v1 = 10002;
  output_2.device_name = "Fake Headphone";
  output_2.type = "HEADPHONE";
  output_2.name = "Headphone";
  node_list_.push_back(output_2);

  AudioNode output_3;
  output_3.is_input = false;
  output_3.id = 10003;
  output_3.stable_device_id_v1 = 10003;
  output_3.device_name = "Fake Bluetooth Headphone";
  output_3.type = "BLUETOOTH";
  output_3.name = "Headphone";
  node_list_.push_back(output_3);

  AudioNode output_4;
  output_4.is_input = false;
  output_4.id = 10004;
  output_4.stable_device_id_v1 = 10004;
  output_4.device_name = "Fake HDMI Speaker";
  output_4.type = "HDMI";
  output_4.name = "HDMI Speaker";
  node_list_.push_back(output_4);

  // Fake audio input nodes
  AudioNode input_1;
  input_1.is_input = true;
  input_1.id = 20001;
  input_1.stable_device_id_v1 = 20001;
  input_1.device_name = "Fake Internal Mic";
  input_1.type = "INTERNAL_MIC";
  input_1.name = "Internal Mic";
  node_list_.push_back(input_1);

  AudioNode input_2;
  input_2.is_input = true;
  input_2.id = 20002;
  input_2.stable_device_id_v1 = 20002;
  input_2.device_name = "Fake USB Mic";
  input_2.type = "USB";
  input_2.name = "Mic";
  node_list_.push_back(input_2);

  AudioNode input_3;
  input_3.is_input = true;
  input_3.id = 20003;
  input_3.stable_device_id_v1 = 20003;
  input_3.device_name = "Fake Mic Jack";
  input_3.type = "MIC";
  input_3.name = "Some type of Mic";
  node_list_.push_back(input_3);
}

void FakeCrasAudioClient::AddObserver(Observer* observer) {
  observers_.AddObserver(observer);
}

void FakeCrasAudioClient::RemoveObserver(Observer* observer) {
  observers_.RemoveObserver(observer);
}

bool FakeCrasAudioClient::HasObserver(const Observer* observer) const {
  return observers_.HasObserver(observer);
}

void FakeCrasAudioClient::GetVolumeState(
    DBusMethodCallback<VolumeState> callback) {
  std::move(callback).Run(volume_state_);
}

void FakeCrasAudioClient::GetDefaultOutputBufferSize(
    DBusMethodCallback<int> callback) {
  std::move(callback).Run(512);
}

void FakeCrasAudioClient::GetNodes(DBusMethodCallback<AudioNodeList> callback) {
  std::move(callback).Run(node_list_);
}

void FakeCrasAudioClient::GetNumberOfActiveOutputStreams(
    DBusMethodCallback<int> callback) {
  std::move(callback).Run(0);
}

void FakeCrasAudioClient::SetOutputNodeVolume(uint64_t node_id,
                                              int32_t volume) {
  if (!notify_volume_change_with_delay_)
    NotifyOutputNodeVolumeChangedForTesting(node_id, volume);
}

void FakeCrasAudioClient::SetOutputUserMute(bool mute_on) {
  volume_state_.output_user_mute = mute_on;
  for (auto& observer : observers_)
    observer.OutputMuteChanged(volume_state_.output_user_mute);
}

void FakeCrasAudioClient::SetInputNodeGain(uint64_t node_id,
                                           int32_t input_gain) {}

void FakeCrasAudioClient::SetInputMute(bool mute_on) {
  volume_state_.input_mute = mute_on;
  for (auto& observer : observers_)
    observer.InputMuteChanged(volume_state_.input_mute);
}

void FakeCrasAudioClient::SetActiveOutputNode(uint64_t node_id) {
  if (active_output_node_id_ == node_id)
    return;

  for (size_t i = 0; i < node_list_.size(); ++i) {
    if (node_list_[i].id == active_output_node_id_)
      node_list_[i].active = false;
    else if (node_list_[i].id == node_id)
      node_list_[i].active = true;
  }
  active_output_node_id_ = node_id;
  for (auto& observer : observers_)
    observer.ActiveOutputNodeChanged(node_id);
}

void FakeCrasAudioClient::SetActiveInputNode(uint64_t node_id) {
  if (active_input_node_id_ == node_id)
    return;

  for (size_t i = 0; i < node_list_.size(); ++i) {
    if (node_list_[i].id == active_input_node_id_)
      node_list_[i].active = false;
    else if (node_list_[i].id == node_id)
      node_list_[i].active = true;
  }
  active_input_node_id_ = node_id;
  for (auto& observer : observers_)
    observer.ActiveInputNodeChanged(node_id);
}

void FakeCrasAudioClient::AddActiveInputNode(uint64_t node_id) {
  for (size_t i = 0; i < node_list_.size(); ++i) {
    if (node_list_[i].id == node_id)
      node_list_[i].active = true;
  }
}

void FakeCrasAudioClient::RemoveActiveInputNode(uint64_t node_id) {
  for (size_t i = 0; i < node_list_.size(); ++i) {
    if (node_list_[i].id == node_id)
      node_list_[i].active = false;
  }
}

void FakeCrasAudioClient::SwapLeftRight(uint64_t node_id, bool swap) {}

void FakeCrasAudioClient::SetGlobalOutputChannelRemix(
    int32_t channels, const std::vector<double>& mixer) {}

void FakeCrasAudioClient::AddActiveOutputNode(uint64_t node_id) {
  for (size_t i = 0; i < node_list_.size(); ++i) {
    if (node_list_[i].id == node_id)
      node_list_[i].active = true;
  }
}

void FakeCrasAudioClient::WaitForServiceToBeAvailable(
    WaitForServiceToBeAvailableCallback callback) {
  std::move(callback).Run(true);
}

void FakeCrasAudioClient::RemoveActiveOutputNode(uint64_t node_id) {
  for (size_t i = 0; i < node_list_.size(); ++i) {
    if (node_list_[i].id == node_id)
      node_list_[i].active = false;
  }
}

void FakeCrasAudioClient::InsertAudioNodeToList(const AudioNode& audio_node) {
  auto iter = FindNode(audio_node.id);
  if (iter != node_list_.end())
    (*iter) = audio_node;
  else
    node_list_.push_back(audio_node);
  for (auto& observer : observers_)
    observer.NodesChanged();
}

void FakeCrasAudioClient::RemoveAudioNodeFromList(const uint64_t& node_id) {
  auto iter = FindNode(node_id);
  if (iter != node_list_.end()) {
    node_list_.erase(iter);
    for (auto& observer : observers_)
      observer.NodesChanged();
  }
}

void FakeCrasAudioClient::SetAudioNodesForTesting(
    const AudioNodeList& audio_nodes) {
  node_list_ = audio_nodes;
}

void FakeCrasAudioClient::SetAudioNodesAndNotifyObserversForTesting(
    const AudioNodeList& new_nodes) {
  SetAudioNodesForTesting(new_nodes);
  for (auto& observer : observers_)
    observer.NodesChanged();
}

void FakeCrasAudioClient::NotifyOutputNodeVolumeChangedForTesting(
    uint64_t node_id,
    int volume) {
  for (auto& observer : observers_)
    observer.OutputNodeVolumeChanged(node_id, volume);
}

void FakeCrasAudioClient::NotifyHotwordTriggeredForTesting(uint64_t tv_sec,
                                                           uint64_t tv_nsec) {
  for (auto& observer : observers_)
    observer.HotwordTriggered(tv_sec, tv_nsec);
}

AudioNodeList::iterator FakeCrasAudioClient::FindNode(uint64_t node_id) {
  return std::find_if(
      node_list_.begin(), node_list_.end(),
      [node_id](const AudioNode& node) { return node_id == node.id; });
}

}  // namespace chromeos
