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

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/time/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

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

namespace cobalt {
namespace media {
namespace sandbox {
namespace {

class RawVideoDecoderSandbox {
 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_ = ::media::CreateShellRawVideoDecoderLinux(
        stream->video_decoder_config(), NULL, false);
#elif defined(__LB_PS3__)
    decoder_ = ::media::CreateShellRawVideoDecoderPS3(
        stream->video_decoder_config(), NULL, false);
#else
    decoder_ = ::media::CreateShellRawVideoDecoderStub(
        stream->video_decoder_config(), NULL, false);
#endif
    stream->Read(Bind(&RawVideoDecoderSandbox::ReadCB, Unretained(this)));
  }

  scoped_refptr<Image> GetCurrentFrame(const base::TimeDelta& time) {
    SB_UNREFERENCED_PARAMETER(time);
    return current_frame_
               ? reinterpret_cast<Image*>(current_frame_->texture_id())
               : NULL;
  }

 private:
  void DecodeCB(const scoped_refptr<DecoderBuffer>& buffer,
                ShellRawVideoDecoder::DecodeStatus status,
                const scoped_refptr<VideoFrame>& frame) {
    scoped_refptr<DemuxerStream> stream =
        demuxer_->GetStream(::media::DemuxerStream::VIDEO);

    if (status == ShellRawVideoDecoder::FRAME_DECODED) {
      DCHECK(frame);

      if (frame->IsEndOfStream()) {
        current_frame_ = NULL;
        decoder_.reset();
        demuxer_->Stop(base::MessageLoop::QuitWhenIdleClosure());
        return;
      } else {
        current_frame_ = frame;
      }
      stream->Read(Bind(&RawVideoDecoderSandbox::ReadCB, Unretained(this)));
    } else if (status == ShellRawVideoDecoder::NEED_MORE_DATA) {
      stream->Read(Bind(&RawVideoDecoderSandbox::ReadCB, Unretained(this)));
    } else if (status == ShellRawVideoDecoder::RETRY_WITH_SAME_BUFFER) {
      if (frame) {
        current_frame_ = frame;
      }
      decoder_->Decode(buffer,
                       BindToCurrentLoop(Bind(&RawVideoDecoderSandbox::DecodeCB,
                                              Unretained(this), buffer)));
    } else {
      NOTREACHED();
    }
  }

  void ReadCB(DemuxerStream::Status status,
              const scoped_refptr<DecoderBuffer>& buffer) {
    DCHECK_EQ(status, DemuxerStream::kOk);
    decoder_->Decode(buffer,
                     BindToCurrentLoop(Bind(&RawVideoDecoderSandbox::DecodeCB,
                                            Unretained(this), buffer)));
  }

  scoped_refptr<Demuxer> demuxer_;
  std::unique_ptr<ShellRawVideoDecoder> 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,
                             base::FilePath(FILE_PATH_LITERAL(
                                 "raw_video_decoder_sandbox_trace.json")));
  RawVideoDecoderSandbox decoder_sandbox;
  DemuxerHelper demuxer_helper(
      base::MessageLoop::current()->task_runner(),
      media_sandbox.GetFetcherFactory(), video_url,
      BindToCurrentLoop(Bind(&RawVideoDecoderSandbox::SetDemuxer,
                             Unretained(&decoder_sandbox))));
  media_sandbox.RegisterFrameCB(Bind(&RawVideoDecoderSandbox::GetCurrentFrame,
                                     Unretained(&decoder_sandbox)));
  base::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);
