// Copyright (c) 2012 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_BASE_PIPELINE_STATUS_H_
#define MEDIA_BASE_PIPELINE_STATUS_H_

#include <stdint.h>
#include <iosfwd>
#include <string>

#include "base/callback.h"
#include "base/time/time.h"
#include "media/base/decoder.h"
#include "media/base/media_export.h"
#include "media/base/status.h"
#include "media/base/timestamp_constants.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace media {

// Status states for pipeline.  All codes except PIPELINE_OK indicate errors.
// Logged to UMA, so never reuse a value, always add new/greater ones!
// When adding a new one, also update enums.xml.
enum PipelineStatus {
  PIPELINE_OK = 0,
  // Deprecated: PIPELINE_ERROR_URL_NOT_FOUND = 1,
  PIPELINE_ERROR_NETWORK = 2,
  PIPELINE_ERROR_DECODE = 3,
  // Deprecated: PIPELINE_ERROR_DECRYPT = 4,
  PIPELINE_ERROR_ABORT = 5,
  PIPELINE_ERROR_INITIALIZATION_FAILED = 6,
  PIPELINE_ERROR_COULD_NOT_RENDER = 8,
  PIPELINE_ERROR_READ = 9,
  // Deprecated: PIPELINE_ERROR_OPERATION_PENDING = 10,
  PIPELINE_ERROR_INVALID_STATE = 11,

  // Demuxer related errors.
  DEMUXER_ERROR_COULD_NOT_OPEN = 12,
  DEMUXER_ERROR_COULD_NOT_PARSE = 13,
  DEMUXER_ERROR_NO_SUPPORTED_STREAMS = 14,

  // Decoder related errors.
  DECODER_ERROR_NOT_SUPPORTED = 15,

  // ChunkDemuxer related errors.
  CHUNK_DEMUXER_ERROR_APPEND_FAILED = 16,
  CHUNK_DEMUXER_ERROR_EOS_STATUS_DECODE_ERROR = 17,
  CHUNK_DEMUXER_ERROR_EOS_STATUS_NETWORK_ERROR = 18,

  // Audio rendering errors.
  AUDIO_RENDERER_ERROR = 19,

  // Deprecated: AUDIO_RENDERER_ERROR_SPLICE_FAILED = 20,
  PIPELINE_ERROR_EXTERNAL_RENDERER_FAILED = 21,

  // Android only. Used as a signal to fallback MediaPlayerRenderer, and thus
  // not exactly an 'error' per say.
  DEMUXER_ERROR_DETECTED_HLS = 22,

  // Used when hardware context is reset (e.g. OS sleep/resume), where we should
  // recreate the Renderer instead of failing the playback. See
  // https://crbug.com/1208618
  PIPELINE_ERROR_HARDWARE_CONTEXT_RESET = 23,

#if defined(STARBOARD)
  // Transient errors.
  PLAYBACK_CAPABILITY_CHANGED = 24,

  PIPELINE_STATUS_MAX = PLAYBACK_CAPABILITY_CHANGED,
#else  // defined(STARBOARD)
  // Must be equal to the largest value ever logged.
  PIPELINE_STATUS_MAX = PIPELINE_ERROR_HARDWARE_CONTEXT_RESET,
#endif  // defined(STARBOARD)
};

MEDIA_EXPORT absl::optional<PipelineStatus> StatusCodeToPipelineStatus(
    StatusCode status);
MEDIA_EXPORT StatusCode PipelineStatusToStatusCode(PipelineStatus status);

// Returns a string version of the status, unique to each PipelineStatus, and
// not including any ':'. This makes it suitable for usage in
// MediaError.message as the UA-specific-error-code.
MEDIA_EXPORT std::string PipelineStatusToString(PipelineStatus status);

MEDIA_EXPORT std::ostream& operator<<(std::ostream& out, PipelineStatus status);

// TODO(crbug.com/1007799): Delete PipelineStatusCB once all callbacks are
//                          converted to PipelineStatusCallback.
using PipelineStatusCB = base::RepeatingCallback<void(PipelineStatus)>;
using PipelineStatusCallback = base::OnceCallback<void(PipelineStatus)>;

// Information on how an audio/video stream is encrypted.
// Warning: Reported to UKM. Do not reuse or change existing values.
// Note: A stream can be marked as clear (unencrypted) or encrypted in the
// config. In a clear stream, all buffers must be clear. In an encrypted stream,
// buffers can be clear or encrypted. The term "clear lead" generally indicates
// the case where an encrypted stream starts with one or more clear buffers. In
// implementation, since a playback can start from the middle of a stream, the
// playback may not hit clear lead even if the stream has clear lead, so it'll
// be reported as `kEncrypted`, which is okay for metrics' purpose.
enum class EncryptionType {
  kNone = 0,                    // No corresponding audio/video stream
  kClear = 1,                   // Stream is clear (not encrypted)
  kEncrypted = 2,               // Stream is encrypted without clear lead
  kEncryptedWithClearLead = 3,  // Stream is encrypted but has clear lead
  kMaxValue = kEncryptedWithClearLead,
};

template <typename DecoderType>
struct PipelineInfo {
  bool is_platform_decoder = false;
  bool has_decrypting_demuxer_stream = false;
  DecoderType decoder_type = DecoderType::kUnknown;
  EncryptionType encryption_type = EncryptionType::kNone;
};

using AudioPipelineInfo = PipelineInfo<AudioDecoderType>;
using VideoPipelineInfo = PipelineInfo<VideoDecoderType>;

template <typename DecoderType>
MEDIA_EXPORT inline bool operator==(const PipelineInfo<DecoderType>& first,
                                    const PipelineInfo<DecoderType>& second) {
  return first.decoder_type == second.decoder_type &&
         first.is_platform_decoder == second.is_platform_decoder &&
         first.has_decrypting_demuxer_stream ==
             second.has_decrypting_demuxer_stream &&
         first.encryption_type == second.encryption_type;
}

template <typename DecoderType>
MEDIA_EXPORT inline bool operator!=(const PipelineInfo<DecoderType>& first,
                                    const PipelineInfo<DecoderType>& second) {
  return !(first == second);
}

template <typename DecoderType>
MEDIA_EXPORT inline std::ostream& operator<<(
    std::ostream& out,
    const PipelineInfo<DecoderType>& info) {
  return out << "{decoder_type:" << GetDecoderName(info.decoder_type) << ","
             << "is_platform_decoder:" << info.is_platform_decoder << ","
             << "has_decrypting_demuxer_stream:"
             << info.has_decrypting_demuxer_stream << ","
             << "encryption_type:" << static_cast<int>(info.encryption_type)
             << "}";
}

struct MEDIA_EXPORT PipelineStatistics {
  PipelineStatistics();
  PipelineStatistics(const PipelineStatistics& other);
  ~PipelineStatistics();

  uint64_t audio_bytes_decoded = 0u;
  uint64_t video_bytes_decoded = 0u;
  uint32_t video_frames_decoded = 0u;
  uint32_t video_frames_dropped = 0u;
  uint32_t video_frames_decoded_power_efficient = 0u;

  int64_t audio_memory_usage = 0;
  int64_t video_memory_usage = 0;

  base::TimeDelta video_keyframe_distance_average = kNoTimestamp;

  // NOTE: frame duration should reflect changes to playback rate.
  base::TimeDelta video_frame_duration_average = kNoTimestamp;

  // Note: Keep these fields at the end of the structure, if you move them you
  // need to also update the test ProtoUtilsTest::PipelineStatisticsConversion.
  AudioPipelineInfo audio_pipeline_info;
  VideoPipelineInfo video_pipeline_info;

  // NOTE: always update operator== implementation in pipeline_status.cc when
  // adding a field to this struct. Leave this comment at the end.
};

MEDIA_EXPORT bool operator==(const PipelineStatistics& first,
                             const PipelineStatistics& second);
MEDIA_EXPORT bool operator!=(const PipelineStatistics& first,
                             const PipelineStatistics& second);

// Used for updating pipeline statistics; the passed value should be a delta
// of all attributes since the last update.
using StatisticsCB = base::RepeatingCallback<void(const PipelineStatistics&)>;

}  // namespace media

#endif  // MEDIA_BASE_PIPELINE_STATUS_H_
