// Copyright 2015 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 "base/bind.h"
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
#include "base/time.h"
#include "cobalt/base/wrap_main.h"
#include "cobalt/media/sandbox/demuxer_helper.h"
#include "cobalt/media/sandbox/media_sandbox.h"
#include "cobalt/render_tree/image.h"
#include "media/base/bind_to_loop.h"
#include "media/base/video_frame.h"
#if defined(__LB_LINUX__)
#include "media/filters/shell_raw_video_decoder_linux.h"
#elif defined(__LB_PS3__)
#include "media/filters/shell_raw_video_decoder_ps3.h"
#else
#include "media/filters/shell_raw_video_decoder_stub.h"
#endif
#include "media/filters/shell_video_decoder_impl.h"

using base::Bind;
using base::Unretained;
using cobalt::render_tree::Image;
using ::media::BindToCurrentLoop;
using ::media::Demuxer;
using ::media::DemuxerStream;
using ::media::PipelineStatus;
using ::media::ShellVideoDecoderImpl;
using ::media::VideoDecoder;
using ::media::VideoFrame;

namespace cobalt {
namespace media {
namespace sandbox {
namespace {

class VideoDecoderSandbox {
 public:
  void SetDemuxer(const scoped_refptr<Demuxer>& demuxer) {
    DCHECK(demuxer);

    scoped_refptr<DemuxerStream> stream =
        demuxer->GetStream(::media::DemuxerStream::VIDEO);
    DCHECK(stream);

    demuxer_ = demuxer;
#if defined(__LB_LINUX__)
    decoder_ = new ShellVideoDecoderImpl(
        base::MessageLoopProxy::current(),
        base::Bind(::media::CreateShellRawVideoDecoderLinux));
#elif defined(__LB_PS3__)
    decoder_ = new ShellVideoDecoderImpl(
        base::MessageLoopProxy::current(),
        base::Bind(::media::CreateShellRawVideoDecoderPS3));
#else
    decoder_ = new ShellVideoDecoderImpl(
        base::MessageLoopProxy::current(),
        base::Bind(::media::CreateShellRawVideoDecoderStub));
#endif
    decoder_->Initialize(
        stream,
        Bind(&VideoDecoderSandbox::VideoDecoderReadyCB, Unretained(this)),
        Bind(&VideoDecoderSandbox::PipelineStatisticsCB, Unretained(this)));
  }

  scoped_refptr<Image> GetCurrentFrame(const base::TimeDelta& time) {
    UNREFERENCED_PARAMETER(time);

    return current_frame_
               ? reinterpret_cast<Image*>(current_frame_->texture_id())
               : NULL;
  }

 private:
  void DecodeFrame(VideoDecoder::Status status,
                   const scoped_refptr<VideoFrame>& frame) {
    DCHECK_EQ(status, VideoDecoder::kOk);

    if (frame) {
      if (frame->IsEndOfStream()) {
        current_frame_ = NULL;
        decoder_->Stop(
            Bind(&Demuxer::Stop, demuxer_, MessageLoop::QuitWhenIdleClosure()));
        return;
      } else {
        current_frame_ = frame;
      }
    }

    decoder_->Read(Bind(&VideoDecoderSandbox::DecodeFrame, Unretained(this)));
  }

  void VideoDecoderReadyCB(PipelineStatus status) {
    // Kick off the first Read().
    decoder_->Read(Bind(&VideoDecoderSandbox::DecodeFrame, Unretained(this)));
  }

  void PipelineStatisticsCB(const ::media::PipelineStatistics&) {}

  scoped_refptr<Demuxer> demuxer_;
  scoped_refptr<VideoDecoder> decoder_;
  scoped_refptr<VideoFrame> current_frame_;
};

int SandboxMain(int argc, char** argv) {
  DCHECK_GT(argc, 1) << " Usage: " << argv[0] << " <url>";
  GURL video_url(argv[1]);
  DCHECK(video_url.is_valid()) << " \"" << argv[1] << "\" is not a valid URL.";

  MediaSandbox media_sandbox(
      argc, argv,
      FilePath(FILE_PATH_LITERAL("video_decoder_sandbox_trace.json")));
  VideoDecoderSandbox decoder_sandbox;
  DemuxerHelper demuxer_helper(
      base::MessageLoopProxy::current(), media_sandbox.GetFetcherFactory(),
      video_url, BindToCurrentLoop(Bind(&VideoDecoderSandbox::SetDemuxer,
                                        Unretained(&decoder_sandbox))));

  media_sandbox.RegisterFrameCB(Bind(&VideoDecoderSandbox::GetCurrentFrame,
                                     Unretained(&decoder_sandbox)));
  MessageLoop::current()->Run();

  LOG(INFO) << "Video playback finished successfully.";

  media_sandbox.RegisterFrameCB(MediaSandbox::FrameCB());

  return 0;
}

}  // namespace
}  // namespace sandbox
}  // namespace media
}  // namespace cobalt

COBALT_WRAP_SIMPLE_MAIN(cobalt::media::sandbox::SandboxMain);
