// Copyright 2016 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 "services/media/framework/graph.h"

namespace mojo {
namespace media {

Graph::Graph() {
  update_function_ = [this](Stage* stage) {
    engine_.RequestUpdate(stage);
  };
}

Graph::~Graph() {
  Reset();
}

void Graph::RemovePart(PartRef part) {
  DCHECK(part.valid());

  Stage* stage = part.stage_;

  size_t input_count = stage->input_count();
  for (size_t input_index = 0; input_index < input_count; input_index++) {
    if (stage->input(input_index).connected()) {
      DisconnectInput(InputRef(stage, input_index));
    }
  }

  size_t output_count = stage->output_count();
  for (size_t output_index = 0; output_index < output_count; output_index++) {
    if (stage->output(output_index).connected()) {
      DisconnectOutput(OutputRef(stage, output_index));
    }
  }

  stage->SetUpdateCallback(nullptr);

  sources_.remove(stage);
  sinks_.remove(stage);
  stages_.remove(stage);

  delete stage;
}

PartRef Graph::Connect(const OutputRef& output, const InputRef& input) {
  DCHECK(output.valid());
  DCHECK(input.valid());

  if (output.connected()) {
    DisconnectOutput(output);
  }
  if (input.connected()) {
    DisconnectInput(input);
  }

  output.actual().Connect(input);
  input.actual().Connect(output);

  return input.part();
}

PartRef Graph::ConnectParts(
    PartRef upstream_part,
    PartRef downstream_part) {
  DCHECK(upstream_part.valid());
  DCHECK(downstream_part.valid());
  Connect(upstream_part.output(), downstream_part.input());
  return downstream_part;
}

PartRef Graph::ConnectOutputToPart(
    const OutputRef& output,
    PartRef downstream_part) {
  DCHECK(output.valid());
  DCHECK(downstream_part.valid());
  Connect(output, downstream_part.input());
  return downstream_part;
}

PartRef Graph::ConnectPartToInput(
    PartRef upstream_part,
    const InputRef& input) {
  DCHECK(upstream_part.valid());
  DCHECK(input.valid());
  Connect(upstream_part.output(), input);
  return input.part();
}

void Graph::DisconnectOutput(const OutputRef& output) {
  DCHECK(output.valid());

  if (!output.connected()) {
    return;
  }

  Input& mate = output.mate().actual();

  if (mate.prepared()) {
    CHECK(false) << "attempt to disconnect prepared output";
    return;
  }

  mate.Disconnect();
  output.actual().Disconnect();
}

void Graph::DisconnectInput(const InputRef& input) {
  DCHECK(input.valid());

  if (!input.connected()) {
    return;
  }

  Output& mate = input.mate().actual();

  if (input.actual().prepared()) {
    CHECK(false) << "attempt to disconnect prepared input";
    return;
  }

  mate.Disconnect();
  input.actual().Disconnect();
}

void Graph::RemovePartsConnectedToPart(PartRef part) {
  DCHECK(part.valid());

  std::deque<PartRef> to_remove { part };

  while (!to_remove.empty()) {
    PartRef part = to_remove.front();
    to_remove.pop_front();

    for (size_t i = 0; i < part.input_count(); ++i) {
      to_remove.push_back(part.input(i).part());
    }

    for (size_t i = 0; i < part.output_count(); ++i) {
      to_remove.push_back(part.output(i).part());
    }

    RemovePart(part);
  }
}

void Graph::RemovePartsConnectedToOutput(const OutputRef& output) {
  DCHECK(output.valid());

  if (!output.connected()) {
    return;
  }

  PartRef downstream_part = output.mate().part();
  DisconnectOutput(output);
  RemovePartsConnectedToPart(downstream_part);
}

void Graph::RemovePartsConnectedToInput(const InputRef& input) {
  DCHECK(input.valid());

  if (!input.connected()) {
    return;
  }

  PartRef upstream_part = input.mate().part();
  DisconnectInput(input);
  RemovePartsConnectedToPart(upstream_part);
}

void Graph::Reset() {
  sources_.clear();
  sinks_.clear();
  while (!stages_.empty()) {
    Stage* stage = stages_.front();
    stages_.pop_front();
    delete stage;
  }
}

void Graph::Prepare() {
  for (Stage* sink : sinks_) {
    for (size_t i = 0; i < sink->input_count(); ++i) {
      engine_.PrepareInput(InputRef(sink, i));
    }
  }
}

void Graph::PrepareInput(const InputRef& input) {
  DCHECK(input.valid());
  engine_.PrepareInput(input);
}

void Graph::PrimeSinks() {
  for (Stage* sink : sinks_) {
    sink->Prime();
  }
}

void Graph::FlushOutput(const OutputRef& output) {
  DCHECK(output);
  engine_.FlushOutput(output);
}

void Graph::FlushAllOutputs(PartRef part) {
  DCHECK(part.valid());
  size_t output_count = part.output_count();
  for (size_t output_index = 0; output_index < output_count; output_index++) {
    FlushOutput(part.output(output_index));
  }
}

PartRef Graph::Add(Stage* stage) {
  stages_.push_back(stage);

  if (stage->input_count() == 0) {
    sources_.push_back(stage);
  }

  if (stage->output_count() == 0) {
    sinks_.push_back(stage);
  }

  stage->SetUpdateCallback(update_function_);

  return PartRef(stage);
}

}  // namespace media
}  // namespace mojo
