// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/media/media_module.h"

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/strings/string_split.h"
#include "base/synchronization/waitable_event.h"
#include "cobalt/media/base/format_support_query_metrics.h"
#include "nb/memory_scope.h"
#include "starboard/common/string.h"
#include "starboard/media.h"
#include "starboard/window.h"
#include "third_party/chromium/media/base/mime_util.h"

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
#include "cobalt/browser/switches.h"
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES

namespace cobalt {
namespace media {

namespace {

// TODO: Determine if ExtractCodecs() and ExtractEncryptionScheme() can be
// combined and simplified.
static std::vector<std::string> ExtractCodecs(const std::string& mime_type) {
  std::vector<std::string> codecs;
  std::vector<std::string> components = base::SplitString(
      mime_type, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  LOG_IF(WARNING, components.empty())
      << "argument mime type \"" << mime_type << "\" is not valid.";
  // The first component is the type/subtype pair. We want to iterate over the
  // remaining components to search for the codecs.
  auto iter = components.begin() + 1;
  for (; iter != components.end(); ++iter) {
    std::vector<std::string> name_and_value = base::SplitString(
        *iter, "=", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    if (name_and_value.size() != 2) {
      LOG(WARNING) << "parameter for mime_type \"" << mime_type
                   << "\" is not valid.";
      continue;
    }
    if (name_and_value[0] == "codecs") {
      ::media::SplitCodecs(name_and_value[1], &codecs);
      return codecs;
    }
  }
  return codecs;
}

static std::string ExtractEncryptionScheme(const std::string& key_system) {
  std::vector<std::string> components = base::SplitString(
      key_system, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

  auto iter = components.begin();
  for (; iter != components.end(); ++iter) {
    std::vector<std::string> name_and_value = base::SplitString(
        *iter, "=", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    if (name_and_value.size() != 1 && name_and_value.size() != 2) {
      LOG(WARNING) << "parameter for key_system \"" << key_system
                   << "\" is not valid.";
      continue;
    }
    if (name_and_value[0] == "encryptionscheme") {
      if (name_and_value.size() < 2) {
        return "";
      }
      base::RemoveChars(name_and_value[1], "\"", &name_and_value[1]);
      return name_and_value[1];
    }
  }
  return "";
}

class CanPlayTypeHandlerStarboard : public CanPlayTypeHandler {
 public:
  void SetDisabledMediaCodecs(
      const std::string& disabled_media_codecs) override {
    disabled_media_codecs_ =
        base::SplitString(disabled_media_codecs, ";", base::TRIM_WHITESPACE,
                          base::SPLIT_WANT_NONEMPTY);
    LOG(INFO) << "Disabled media codecs \"" << disabled_media_codecs
              << "\" from console/command line.";
  }

  void SetDisabledMediaEncryptionSchemes(
      const std::string& disabled_encryption_schemes) override {
    disabled_encryption_schemes_ =
        base::SplitString(disabled_encryption_schemes, ";",
                          base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    LOG(INFO) << "Disabled encryption scheme(s) \""
              << disabled_encryption_schemes << "\" from command line.";
  }

  SbMediaSupportType CanPlayProgressive(
      const std::string& mime_type) const override {
    // |mime_type| is something like:
    //   video/mp4
    //   video/webm
    //   video/mp4; codecs="avc1.4d401e"
    //   video/webm; codecs="vp9"
    // We do a rough pre-filter to ensure that only video/mp4 is supported as
    // progressive.
    SbMediaSupportType support_type;
    media::FormatSupportQueryMetrics metrics;
    if (strstr(mime_type.c_str(), "video/mp4") == 0 &&
        strstr(mime_type.c_str(), "application/x-mpegURL") == 0) {
      support_type = kSbMediaSupportTypeNotSupported;
    } else {
      support_type = CanPlayType(mime_type, "");
    }
    metrics.RecordAndLogQuery("HTMLMediaElement::canPlayType", mime_type, "",
                              support_type);
    return support_type;
  }

  SbMediaSupportType CanPlayAdaptive(
      const std::string& mime_type,
      const std::string& key_system) const override {
    media::FormatSupportQueryMetrics metrics;
    SbMediaSupportType support_type = CanPlayType(mime_type, key_system);
    metrics.RecordAndLogQuery("MediaSource::IsTypeSupported", mime_type,
                              key_system, support_type);
    return support_type;
  }

 private:
  SbMediaSupportType CanPlayType(const std::string& mime_type,
                                 const std::string& key_system) const {
    if (!disabled_media_codecs_.empty()) {
      auto mime_codecs = ExtractCodecs(mime_type);
      for (auto& disabled_codec : disabled_media_codecs_) {
        for (auto& mime_codec : mime_codecs) {
          if (mime_codec.find(disabled_codec) != std::string::npos) {
            LOG(INFO) << "Codec (" << mime_codec
                      << ") is disabled via console/command line.";
            return kSbMediaSupportTypeNotSupported;
          }
        }
      }
    }

    if (!disabled_encryption_schemes_.empty()) {
      std::string encryption_scheme = ExtractEncryptionScheme(key_system);
      if (std::find(disabled_encryption_schemes_.begin(),
                    disabled_encryption_schemes_.end(),
                    encryption_scheme) != disabled_encryption_schemes_.end()) {
        LOG(INFO) << "Encryption scheme (" << encryption_scheme
                  << ") is disabled via console/command line.";
        return kSbMediaSupportTypeNotSupported;
      }
    }
    SbMediaSupportType type =
        SbMediaCanPlayMimeAndKeySystem(mime_type.c_str(), key_system.c_str());
    return type;
  }

  // List of disabled media codecs that will be treated as unsupported.
  std::vector<std::string> disabled_media_codecs_;
  // List of disabled DRM encryption schemes that will be treated as
  // unsupported.
  std::vector<std::string> disabled_encryption_schemes_;
};

}  // namespace

bool MediaModule::SetConfiguration(const std::string& name, int32 value) {
  if (name == "source_buffer_evict_extra_in_bytes" && value >= 0) {
    decoder_buffer_allocator_.SetSourceBufferEvictExtraInBytes(value);
    return true;
  }
  return false;
}

std::unique_ptr<WebMediaPlayer> MediaModule::CreateWebMediaPlayer(
    WebMediaPlayerClient* client) {
  TRACK_MEMORY_SCOPE("Media");
  SbWindow window = kSbWindowInvalid;
  if (system_window_) {
    window = system_window_->GetSbWindow();
  }

  return std::unique_ptr<WebMediaPlayer>(new media::WebMediaPlayerImpl(
      window,
      base::Bind(&MediaModule::GetSbDecodeTargetGraphicsContextProvider,
                 base::Unretained(this)),
      client, this, options_.allow_resume_after_suspend, &media_log_));
}

void MediaModule::Suspend() {
  starboard::ScopedLock scoped_lock(players_lock_);

  suspended_ = true;

  for (Players::iterator iter = players_.begin(); iter != players_.end();
       ++iter) {
    DCHECK(!iter->second);
    if (!iter->second) {
      iter->first->Suspend();
    }
  }

  decoder_buffer_allocator_.Suspend();

  resource_provider_ = NULL;
}

void MediaModule::Resume(render_tree::ResourceProvider* resource_provider) {
  starboard::ScopedLock scoped_lock(players_lock_);

  resource_provider_ = resource_provider;

  SbWindow window = kSbWindowInvalid;
  if (system_window_) {
    window = system_window_->GetSbWindow();
  }

  decoder_buffer_allocator_.Resume();

  for (Players::iterator iter = players_.begin(); iter != players_.end();
       ++iter) {
    DCHECK(!iter->second);
    if (!iter->second) {
      iter->first->Resume(window);
    }
  }

  suspended_ = false;
}

void MediaModule::RegisterPlayer(WebMediaPlayer* player) {
  starboard::ScopedLock scoped_lock(players_lock_);

  DCHECK(players_.find(player) == players_.end());
  players_.insert(std::make_pair(player, false));

  if (suspended_) {
    player->Suspend();
  }
}

void MediaModule::UnregisterPlayer(WebMediaPlayer* player) {
  starboard::ScopedLock scoped_lock(players_lock_);

  DCHECK(players_.find(player) != players_.end());
  players_.erase(players_.find(player));
}

void MediaModule::EnumerateWebMediaPlayers(
    const EnumeratePlayersCB& enumerate_callback) const {
  starboard::ScopedLock scoped_lock(players_lock_);

  for (Players::const_iterator iter = players_.begin(); iter != players_.end();
       ++iter) {
    enumerate_callback.Run(iter->first);
  }
}

std::unique_ptr<CanPlayTypeHandler> MediaModule::CreateCanPlayTypeHandler() {
  return std::unique_ptr<CanPlayTypeHandler>(new CanPlayTypeHandlerStarboard);
}

}  // namespace media
}  // namespace cobalt
