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

#include "media/formats/webm/webm_tracks_parser.h"

#include <memory>

#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "media/base/media_util.h"
#include "media/base/timestamp_constants.h"
#include "media/formats/webm/webm_constants.h"
#include "media/formats/webm/webm_content_encodings.h"

namespace media {

static TextKind CodecIdToTextKind(const std::string& codec_id) {
  if (codec_id == kWebMCodecSubtitles)
    return kTextSubtitles;

  if (codec_id == kWebMCodecCaptions)
    return kTextCaptions;

  if (codec_id == kWebMCodecDescriptions)
    return kTextDescriptions;

  if (codec_id == kWebMCodecMetadata)
    return kTextMetadata;

  return kTextNone;
}

WebMTracksParser::WebMTracksParser(MediaLog* media_log, bool ignore_text_tracks)
    : ignore_text_tracks_(ignore_text_tracks),
      media_log_(media_log),
      audio_client_(media_log),
      video_client_(media_log) {
  Reset();
}

WebMTracksParser::~WebMTracksParser() = default;

base::TimeDelta WebMTracksParser::PrecisionCappedDefaultDuration(
    const int64_t timecode_scale_in_ns,
    const int64_t duration_in_ns) const {
  DCHECK_GT(timecode_scale_in_ns, 0);
  if (duration_in_ns <= 0)
    return kNoTimestamp;

  // Calculate the (integral) number of complete |timecode_scale_in_ns|
  // intervals that fit within |duration_in_ns|.
  int64_t intervals = duration_in_ns / timecode_scale_in_ns;

  int64_t result_us = (intervals * timecode_scale_in_ns) / 1000;
  if (result_us == 0)
    return kNoTimestamp;

  return base::Microseconds(result_us);
}

void WebMTracksParser::Reset() {
  ResetTrackEntry();
  reset_on_next_parse_ = false;
  audio_track_num_ = -1;
  audio_default_duration_ = -1;
  audio_decoder_config_ = AudioDecoderConfig();
  video_track_num_ = -1;
  video_default_duration_ = -1;
  video_decoder_config_ = VideoDecoderConfig();
  text_tracks_.clear();
  ignored_tracks_.clear();
  detected_audio_track_count_ = 0;
  detected_video_track_count_ = 0;
  detected_text_track_count_ = 0;
  media_tracks_ = std::make_unique<MediaTracks>();
}

void WebMTracksParser::ResetTrackEntry() {
  track_type_ = -1;
  track_num_ = -1;
  track_name_.clear();
  track_language_.clear();
  codec_id_ = "";
  codec_private_.clear();
  seek_preroll_ = -1;
  codec_delay_ = -1;
  default_duration_ = -1;
  audio_client_.Reset();
  video_client_.Reset();
}

int WebMTracksParser::Parse(const uint8_t* buf, int size) {
  if (reset_on_next_parse_)
    Reset();

  reset_on_next_parse_ = true;

  WebMListParser parser(kWebMIdTracks, this);
  int result = parser.Parse(buf, size);

  if (result <= 0)
    return result;

  // For now we do all or nothing parsing.
  return parser.IsParsingComplete() ? result : 0;
}

base::TimeDelta WebMTracksParser::GetAudioDefaultDuration(
    const int64_t timecode_scale_in_ns) const {
  return PrecisionCappedDefaultDuration(timecode_scale_in_ns,
                                        audio_default_duration_);
}

base::TimeDelta WebMTracksParser::GetVideoDefaultDuration(
    const int64_t timecode_scale_in_ns) const {
  return PrecisionCappedDefaultDuration(timecode_scale_in_ns,
                                        video_default_duration_);
}

WebMParserClient* WebMTracksParser::OnListStart(int id) {
  if (id == kWebMIdContentEncodings) {
    if (track_content_encodings_client_) {
      MEDIA_LOG(ERROR, media_log_) << "Multiple ContentEncodings lists";
      return NULL;
    }

    track_content_encodings_client_ =
        std::make_unique<WebMContentEncodingsClient>(media_log_);
    return track_content_encodings_client_->OnListStart(id);
  }

  if (id == kWebMIdTrackEntry) {
    ResetTrackEntry();
    return this;
  }

  if (id == kWebMIdAudio)
    return &audio_client_;

  if (id == kWebMIdVideo)
    return &video_client_;

  return this;
}

bool WebMTracksParser::OnListEnd(int id) {
  if (id == kWebMIdContentEncodings) {
    DCHECK(track_content_encodings_client_.get());
    return track_content_encodings_client_->OnListEnd(id);
  }

  if (id == kWebMIdTrackEntry) {
    if (track_type_ == -1 || track_num_ == -1) {
      MEDIA_LOG(ERROR, media_log_) << "Missing TrackEntry data for "
                                   << " TrackType " << track_type_
                                   << " TrackNum " << track_num_;
      return false;
    }

    if (track_type_ != kWebMTrackTypeAudio &&
        track_type_ != kWebMTrackTypeVideo &&
        track_type_ != kWebMTrackTypeSubtitlesOrCaptions &&
        track_type_ != kWebMTrackTypeDescriptionsOrMetadata) {
      MEDIA_LOG(ERROR, media_log_) << "Unexpected TrackType " << track_type_;
      return false;
    }

    TextKind text_track_kind = kTextNone;
    if (track_type_ == kWebMTrackTypeSubtitlesOrCaptions) {
      text_track_kind = CodecIdToTextKind(codec_id_);
      if (text_track_kind == kTextNone) {
        MEDIA_LOG(ERROR, media_log_) << "Missing TrackEntry CodecID"
                                     << " TrackNum " << track_num_;
        return false;
      }

      if (text_track_kind != kTextSubtitles &&
          text_track_kind != kTextCaptions) {
        MEDIA_LOG(ERROR, media_log_) << "Wrong TrackEntry CodecID"
                                     << " TrackNum " << track_num_;
        return false;
      }
    } else if (track_type_ == kWebMTrackTypeDescriptionsOrMetadata) {
      text_track_kind = CodecIdToTextKind(codec_id_);
      if (text_track_kind == kTextNone) {
        MEDIA_LOG(ERROR, media_log_) << "Missing TrackEntry CodecID"
                                     << " TrackNum " << track_num_;
        return false;
      }

      if (text_track_kind != kTextDescriptions &&
          text_track_kind != kTextMetadata) {
        MEDIA_LOG(ERROR, media_log_) << "Wrong TrackEntry CodecID"
                                     << " TrackNum " << track_num_;
        return false;
      }
    }

    std::string encryption_key_id;
    if (track_content_encodings_client_) {
      DCHECK(!track_content_encodings_client_->content_encodings().empty());
      // If we have multiple ContentEncoding in one track. Always choose the
      // key id in the first ContentEncoding as the key id of the track.
      encryption_key_id = track_content_encodings_client_->
          content_encodings()[0]->encryption_key_id();
    }

    EncryptionScheme encryption_scheme = encryption_key_id.empty()
                                             ? EncryptionScheme::kUnencrypted
                                             : EncryptionScheme::kCenc;

    if (track_type_ == kWebMTrackTypeAudio) {
      detected_audio_track_count_++;
      if (audio_track_num_ == -1) {
        audio_track_num_ = track_num_;
        audio_encryption_key_id_ = encryption_key_id;

        if (default_duration_ == 0) {
          MEDIA_LOG(ERROR, media_log_) << "Illegal 0ns audio TrackEntry "
                                          "DefaultDuration";
          return false;
        }
        audio_default_duration_ = default_duration_;

        DCHECK(!audio_decoder_config_.IsValidConfig());
        if (!audio_client_.InitializeConfig(
                codec_id_, codec_private_, seek_preroll_, codec_delay_,
                encryption_scheme, &audio_decoder_config_)) {
          return false;
        }
        media_tracks_->AddAudioTrack(
            audio_decoder_config_,
            static_cast<StreamParser::TrackId>(track_num_),
            MediaTrack::Kind("main"), MediaTrack::Label(track_name_),
            MediaTrack::Language(track_language_));
      } else {
        MEDIA_LOG(DEBUG, media_log_) << "Ignoring audio track " << track_num_;
        ignored_tracks_.insert(track_num_);
      }
    } else if (track_type_ == kWebMTrackTypeVideo) {
      detected_video_track_count_++;
      if (video_track_num_ == -1) {
        video_track_num_ = track_num_;
        video_encryption_key_id_ = encryption_key_id;

        if (default_duration_ == 0) {
          MEDIA_LOG(ERROR, media_log_) << "Illegal 0ns video TrackEntry "
                                          "DefaultDuration";
          return false;
        }
        video_default_duration_ = default_duration_;

        DCHECK(!video_decoder_config_.IsValidConfig());
        if (!video_client_.InitializeConfig(codec_id_, codec_private_,
                                            encryption_scheme,
                                            &video_decoder_config_)) {
          return false;
        }
        media_tracks_->AddVideoTrack(
            video_decoder_config_,
            static_cast<StreamParser::TrackId>(track_num_),
            MediaTrack::Kind("main"), MediaTrack::Label(track_name_),
            MediaTrack::Language(track_language_));
      } else {
        MEDIA_LOG(DEBUG, media_log_) << "Ignoring video track " << track_num_;
        ignored_tracks_.insert(track_num_);
      }
    } else if (track_type_ == kWebMTrackTypeSubtitlesOrCaptions ||
               track_type_ == kWebMTrackTypeDescriptionsOrMetadata) {
      detected_text_track_count_++;
      if (ignore_text_tracks_) {
        MEDIA_LOG(DEBUG, media_log_) << "Ignoring text track " << track_num_;
        ignored_tracks_.insert(track_num_);
      } else {
        std::string track_num = base::NumberToString(track_num_);
        text_tracks_[track_num_] = TextTrackConfig(
            text_track_kind, track_name_, track_language_, track_num);
      }
    } else {
      MEDIA_LOG(ERROR, media_log_) << "Unexpected TrackType " << track_type_;
      return false;
    }

    track_type_ = -1;
    track_num_ = -1;
    default_duration_ = -1;
    track_name_.clear();
    track_language_.clear();
    codec_id_ = "";
    codec_private_.clear();
    track_content_encodings_client_.reset();

    audio_client_.Reset();
    video_client_.Reset();
    return true;
  }

  return true;
}

bool WebMTracksParser::OnUInt(int id, int64_t val) {
  int64_t* dst = NULL;

  switch (id) {
    case kWebMIdTrackNumber:
      dst = &track_num_;
      break;
    case kWebMIdTrackType:
      dst = &track_type_;
      break;
    case kWebMIdSeekPreRoll:
      dst = &seek_preroll_;
      break;
    case kWebMIdCodecDelay:
      dst = &codec_delay_;
      break;
    case kWebMIdDefaultDuration:
      dst = &default_duration_;
      break;
    default:
      return true;
  }

  if (*dst != -1) {
    MEDIA_LOG(ERROR, media_log_) << "Multiple values for id " << std::hex << id
                                 << " specified";
    return false;
  }

  *dst = val;
  return true;
}

bool WebMTracksParser::OnFloat(int id, double val) {
  return true;
}

bool WebMTracksParser::OnBinary(int id, const uint8_t* data, int size) {
  if (id == kWebMIdCodecPrivate) {
    if (!codec_private_.empty()) {
      MEDIA_LOG(ERROR, media_log_)
          << "Multiple CodecPrivate fields in a track.";
      return false;
    }
    codec_private_.assign(data, data + size);
    return true;
  }
  return true;
}

bool WebMTracksParser::OnString(int id, const std::string& str) {
  if (id == kWebMIdCodecID) {
    if (!codec_id_.empty()) {
      MEDIA_LOG(ERROR, media_log_) << "Multiple CodecID fields in a track";
      return false;
    }

    // This element is specified to be printable ASCII (0x20-0x7F). Here, we
    // allow also 0x01-0x1F.
    if (!base::IsStringASCII(str)) {
      MEDIA_LOG(ERROR, media_log_)
          << "Tracks CodecID element value must be an ASCII string";
      return false;
    }

    codec_id_ = str;
    return true;
  }

  if (id == kWebMIdName) {
    // This element is specified to be printable ASCII (0x20-0x7F). Here, we
    // allow also 0x01-0x1F.
    if (!base::IsStringASCII(str)) {
      MEDIA_LOG(ERROR, media_log_)
          << "Tracks Name element value must be an ASCII string";
      return false;
    }
    track_name_ = str;
    return true;
  }

  if (id == kWebMIdLanguage) {
    // Check that the language string is in ISO 639-2 format (3 letter code of a
    // language, all lower-case letters).
    if (str.size() != 3 || str[0] < 'a' || str[0] > 'z' || str[1] < 'a' ||
        str[1] > 'z' || str[2] < 'a' || str[2] > 'z') {
      VLOG(2) << "Ignoring kWebMIdLanguage (not ISO 639-2 compliant): " << str;
      track_language_ = "und";
    } else {
      track_language_ = str;
    }
    return true;
  }

  return true;
}

}  // namespace media
