// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_MEDIA_PLAYBACK_MEDIAPLAYER_CORE_PLAYER_CORE_H_
#define SRC_MEDIA_PLAYBACK_MEDIAPLAYER_CORE_PLAYER_CORE_H_

#include <fuchsia/media/cpp/fidl.h>
#include <lib/async/dispatcher.h>

#include <unordered_map>
#include <vector>

#include "lib/media/timeline/timeline_function.h"
#include "src/media/playback/mediaplayer/core/sink_segment.h"
#include "src/media/playback/mediaplayer/core/source_segment.h"
#include "src/media/playback/mediaplayer/graph/graph.h"
#include "src/media/playback/mediaplayer/graph/metadata.h"

namespace media_player {

// A graph that delivers content one origin to many destinations.
class PlayerCore {
 public:
  PlayerCore(async_dispatcher_t* dispatcher);

  ~PlayerCore();

  // Sets the callback to be called when the status of the player is updated.
  // This callback notifies of changes to end_of_stream(), duration_ns(),
  // metadata() and/or problem().
  void SetUpdateCallback(fit::closure update_callback) {
    update_callback_ = std::move(update_callback);
  }

  // Sets the current source segment. |source_segment| must be provisioned. The
  // callback is called when the initial set of streams supplied by the segment
  // have been connected.
  void SetSourceSegment(std::unique_ptr<SourceSegment> source_segment,
                        fit::closure callback);

  // Removes the current source segment, if there is one.
  void ClearSourceSegment();

  // Sets the current sink segment for the specified medium. |sink_segment| may
  // be null, indicating there is no sink segment for the specified medium.
  void SetSinkSegment(std::unique_ptr<SinkSegment> sink_segment,
                      StreamType::Medium medium);

  // Indicates whether the player has a source segment.
  bool has_source_segment() const { return !!source_segment_; }

  // Indicates whether the player has a sink segment for the specified medium.
  bool has_sink_segment(StreamType::Medium medium) const {
    if (GetParkedSinkSegment(medium)) {
      return true;
    }

    const Stream* stream = GetStream(medium);
    return stream && stream->sink_segment_;
  }

  // Indicates whether the currently-loaded content has a stream with the
  // specified medium.
  bool content_has_medium(StreamType::Medium medium) const {
    return !!GetStream(medium);
  }

  // Indicates whether the indicated medium is connected to a sink segment. This
  // will be false if no sink segment for the specified medium has been supplied
  // or the provided sink segment could not handle the stream type.
  bool medium_connected(StreamType::Medium medium) const {
    const Stream* stream = GetStream(medium);
    return stream && stream->sink_segment_ &&
           stream->sink_segment_->connected();
  }

  // Prepares the graph for playback by satisfying initial renderer demand.
  // |callback| will never be called synchronously.
  void Prime(fit::closure callback);

  // Flushes packets from the graph. |callback| will never be called
  // synchronously.
  void Flush(bool hold_frame, fit::closure callback);

  // Sets the timeline function. |callback| will never be called synchronously.
  void SetTimelineFunction(media::TimelineFunction timeline_function,
                           fit::closure callback);

  const media::TimelineFunction& timeline_function() {
    return timeline_function_;
  }

  // Sets a program range for the renderers.
  void SetProgramRange(uint64_t program, int64_t min_pts, int64_t max_pts);

  // Seeks to the specified position. |callback| will never be called
  // synchronously.
  void Seek(int64_t position, fit::closure callback);

  // Indicates whether the player has reached end of stream.
  bool end_of_stream() const;

  // Returns the duration of the content in nanoseconds or 0 if the duration is
  // currently unknown.
  int64_t duration_ns() const;

  // Indicates whether the player can pause. Returns false if this information
  // is currently unknown.
  bool can_pause() const;

  // Indicates whether the player can seek. Returns false if this information
  // is currently unknown.
  bool can_seek() const;

  // Returns the metadata for the current content or nullptr if no metadata
  // has been obtained.
  // TODO(dalesat): Remove metadata concerns from the player and source
  // segment.
  const Metadata* metadata() const;

  // Returns the current problem preventing intended operation or nullptr if
  // there is no such problem.
  const fuchsia::media::playback::Problem* problem() const;

  // Returns a pointer to the graph.
  Graph* graph() { return &graph_; }

  // Test only.
  // Returns a reference to the source node.
  NodeRef source_node() const {
    return source_segment_ ? source_segment_->source_node() : NodeRef();
  }

  // Generates an introspection report.
  void Dump(std::ostream& os) const;

 private:
  static constexpr int64_t kMinimumLeadTime = ZX_MSEC(30);

  struct Stream {
    std::unique_ptr<SinkSegment> sink_segment_;
    std::unique_ptr<StreamType> stream_type_;
    OutputRef output_;
  };

  // Calls the update callback.
  void NotifyUpdate();

  // Gets the stream for the specified medium. Returns nullptr if there is no
  // stream for that medium.
  const Stream* GetStream(StreamType::Medium medium) const;

  // Gets the stream for the specified medium. Returns nullptr if there is no
  // stream for that medium.
  Stream* GetStream(StreamType::Medium medium);

  // Sets a parked sink segment for the specified medium. Returns nullptr if
  // there is no parked sink segment for that medium.
  SinkSegment* GetParkedSinkSegment(StreamType::Medium medium) const;

  // Called when the source segment signals that a stream has been updated.
  void OnStreamUpdated(size_t index, const SourceSegment::Stream& stream);

  // Called when the source segment signals that a stream has been removed.
  void OnStreamRemoved(size_t index);

  // Called when an action kicked off by a call to |SetSourceSegment| completes.
  // If |set_source_segment_callback_| is set, |set_source_segment_countdown_|
  // is decremented. If it transitions to zero, |set_source_segment_callback_|
  // is called and cleared.
  void MaybeCompleteSetSourceSegment();

  // Takes a sink segment for the specified medium from |parked_sink_segments_|
  // or a stream. Returns null if no sink segment has been registered for the
  // specified medium.
  std::unique_ptr<SinkSegment> TakeSinkSegment(StreamType::Medium medium);

  // Takes the sink segment from a stream.
  std::unique_ptr<SinkSegment> TakeSinkSegment(Stream* stream);

  // Connects the specified stream.
  void ConnectStream(Stream* stream);

  Graph graph_;
  async_dispatcher_t* dispatcher_;
  fit::closure update_callback_;
  fit::closure set_source_segment_callback_;
  size_t set_source_segment_countdown_;
  std::unique_ptr<SourceSegment> source_segment_;
  std::vector<Stream> streams_;
  std::unordered_map<StreamType::Medium, std::unique_ptr<SinkSegment>>
      parked_sink_segments_;
  bool primed_ = false;
  media::TimelineFunction timeline_function_;
};

}  // namespace media_player

#endif  // SRC_MEDIA_PLAYBACK_MEDIAPLAYER_CORE_PLAYER_CORE_H_
