// Copyright 2014 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.

#ifndef MEDIA_CAST_LOGGING_RAW_EVENT_SUBSCRIBER_BUNDLE_H_
#define MEDIA_CAST_LOGGING_RAW_EVENT_SUBSCRIBER_BUNDLE_H_

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "media/cast/logging/encoding_event_subscriber.h"
#include "media/cast/logging/stats_event_subscriber.h"

namespace media {
namespace cast {

class CastEnvironment;
class ReceiverTimeOffsetEstimator;

// Allow 9MB for serialized video / audio event logs.
const int kMaxSerializedBytes = 9000000;

// Assume serialized log data for each frame will take up to 150 bytes.
const int kMaxVideoEventEntries = kMaxSerializedBytes / 150;

// Assume serialized log data for each frame will take up to 75 bytes.
const int kMaxAudioEventEntries = kMaxSerializedBytes / 75;

// A bundle for raw event subscribers for a single stream.
// It contains an EncodingEventSubscriber and a StatsSubscriber.
class RawEventSubscriberBundleForStream {
 public:
  RawEventSubscriberBundleForStream(
      const scoped_refptr<CastEnvironment>& cast_environment,
      bool is_audio,
      ReceiverTimeOffsetEstimator* offset_estimator);
  ~RawEventSubscriberBundleForStream();

  EncodingEventSubscriber* GetEncodingEventSubscriber();
  StatsEventSubscriber* GetStatsEventSubscriber();

 private:
  const scoped_refptr<CastEnvironment> cast_environment_;
  EncodingEventSubscriber event_subscriber_;
  StatsEventSubscriber stats_subscriber_;

  DISALLOW_COPY_AND_ASSIGN(RawEventSubscriberBundleForStream);
};

// A bundle of subscribers for all streams. An instance of this object
// is associated with a CastEnvironment.
// This class can be used for managing event subscribers
// in a session where they could be multiple streams (i.e. CastSessionDelegate).
// It also contains a ReceiverTimeOffsetEstimator that is shared by subscribers
// of different streams.
class RawEventSubscriberBundle {
 public:
  explicit RawEventSubscriberBundle(
      const scoped_refptr<CastEnvironment>& cast_environment);
  ~RawEventSubscriberBundle();

  void AddEventSubscribers(bool is_audio);
  void RemoveEventSubscribers(bool is_audio);
  EncodingEventSubscriber* GetEncodingEventSubscriber(
      bool is_audio);
  StatsEventSubscriber* GetStatsEventSubscriber(bool is_audio);

 private:
  // Map from (is_audio) -> RawEventSubscriberBundleForStream.
  // TODO(imcheng): This works because we only have 1 audio and 1 video stream.
  // This needs to scale better.
  typedef std::map<bool, linked_ptr<RawEventSubscriberBundleForStream> >
      SubscribersMapByStream;
  const scoped_refptr<CastEnvironment> cast_environment_;
  SubscribersMapByStream subscribers_;
  std::unique_ptr<ReceiverTimeOffsetEstimator> receiver_offset_estimator_;

  DISALLOW_COPY_AND_ASSIGN(RawEventSubscriberBundle);
};

}  // namespace cast
}  // namespace media

#endif  // MEDIA_CAST_LOGGING_RAW_EVENT_SUBSCRIBER_BUNDLE_H_

