// Copyright 2018 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_capture/media_recorder.h"

#include <memory>

#include "cobalt/dom/dom_exception.h"
#include "cobalt/dom/testing/mock_event_listener.h"
#include "cobalt/dom/testing/stub_window.h"
#include "cobalt/media_capture/media_recorder_options.h"
#include "cobalt/media_stream/media_stream.h"
#include "cobalt/media_stream/media_stream_audio_source.h"
#include "cobalt/media_stream/media_stream_audio_track.h"
#include "cobalt/media_stream/testing/mock_media_stream_audio_track.h"
#include "cobalt/script/testing/fake_script_value.h"
#include "cobalt/script/testing/mock_exception_state.h"
#include "testing/gtest/include/gtest/gtest.h"

using cobalt::dom::EventListener;
using cobalt::dom::testing::MockEventListener;
using cobalt::script::testing::FakeScriptValue;
using cobalt::script::testing::MockExceptionState;
using ::testing::_;
using ::testing::Eq;
using ::testing::Pointee;
using ::testing::Property;
using ::testing::SaveArg;
using ::testing::StrictMock;

namespace {
void PushData(cobalt::media_capture::MediaRecorder* media_recorder) {
  const int kSampleRate = 16000;
  cobalt::media_stream::AudioParameters params(1, kSampleRate, 16);
  media_recorder->OnSetFormat(params);

  std::vector<int16> frames;
  frames.push_back(1);
  frames.push_back(-1);
  frames.push_back(-32768);
  frames.push_back(32767);
  frames.push_back(1000);
  frames.push_back(0);
  cobalt::media_stream::MediaStreamAudioTrack::ShellAudioBus audio_bus(
      1, frames.size(), frames.data());
  base::TimeTicks current_time = base::TimeTicks::Now();
  media_recorder->OnData(audio_bus, current_time);
}

}  // namespace

namespace cobalt {
namespace media_stream {

class FakeMediaStreamAudioSource : public MediaStreamAudioSource {
 public:
  MOCK_METHOD0(EnsureSourceIsStarted, bool());
  MOCK_METHOD0(EnsureSourceIsStopped, void());

  void DeliverDataToTracks(
      const MediaStreamAudioTrack::ShellAudioBus& audio_bus,
      base::TimeTicks reference_time) {
    MediaStreamAudioSource::DeliverDataToTracks(audio_bus, reference_time);
  }

  void SetFormat(const media_stream::AudioParameters& params) {
    MediaStreamAudioSource::SetFormat(params);
  }
};

}  // namespace media_stream

namespace media_capture {

class MediaRecorderTest : public ::testing::Test {
 protected:
  MediaRecorderTest() {
    audio_track_ = new StrictMock<media_stream::MockMediaStreamAudioTrack>(
        stub_window_.environment_settings());
    auto audio_track = base::WrapRefCounted(audio_track_);
    media_stream::MediaStream::TrackSequences sequences;
    sequences.push_back(audio_track);
    audio_track->Start(base::Closure(base::Bind([]() {} /*Do nothing*/)));
    auto stream = base::WrapRefCounted(new media_stream::MediaStream(
        stub_window_.environment_settings(), sequences));
    media_source_ = new StrictMock<media_stream::FakeMediaStreamAudioSource>();
    EXPECT_CALL(*media_source_, EnsureSourceIsStarted());
    EXPECT_CALL(*media_source_, EnsureSourceIsStopped());
    media_source_->ConnectToTrack(audio_track);
    media_recorder_ =
        new MediaRecorder(stub_window_.environment_settings(), stream,
                          MediaRecorderOptions(), &exception_state_);
  }

 protected:
  dom::testing::StubWindow stub_window_;
  scoped_refptr<media_capture::MediaRecorder> media_recorder_;
  StrictMock<media_stream::MockMediaStreamAudioTrack>* audio_track_;
  scoped_refptr<StrictMock<media_stream::FakeMediaStreamAudioSource>>
      media_source_;
  StrictMock<MockExceptionState> exception_state_;
};

TEST_F(MediaRecorderTest, CanSupportMimeType) {
  EXPECT_TRUE(MediaRecorder::IsTypeSupported("audio/L16"));
  EXPECT_TRUE(MediaRecorder::IsTypeSupported("audio/l16"));
  EXPECT_TRUE(
      MediaRecorder::IsTypeSupported("audio/l16;endianness=little-endian"));

  EXPECT_FALSE(MediaRecorder::IsTypeSupported("audio/pcm"));
  EXPECT_FALSE(MediaRecorder::IsTypeSupported("audio/webm"));
  EXPECT_FALSE(MediaRecorder::IsTypeSupported("pcm"));
  EXPECT_FALSE(MediaRecorder::IsTypeSupported("L16"));
  EXPECT_FALSE(MediaRecorder::IsTypeSupported("L16"));
}

TEST_F(MediaRecorderTest, StartStopStartStop) {
  EXPECT_CALL(*audio_track_, Stop()).Times(2);
  media_recorder_->Start(&exception_state_);
  media_recorder_->Stop(&exception_state_);
  media_recorder_->Start(&exception_state_);
  media_recorder_->Stop(&exception_state_);
}

TEST_F(MediaRecorderTest, ExceptionOnStartingTwiceWithoutStop) {
  scoped_refptr<script::ScriptException> exception;

  EXPECT_CALL(exception_state_, SetException(_))
      .WillOnce(SaveArg<0>(&exception));

  media_recorder_->Start(&exception_state_);
  media_recorder_->Start(&exception_state_);

  ASSERT_TRUE(exception.get());
  dom::DOMException& dom_exception(
      *base::polymorphic_downcast<dom::DOMException*>(exception.get()));
  EXPECT_EQ(dom::DOMException::kInvalidStateErr, dom_exception.code());
  EXPECT_EQ(dom_exception.message(), "Recording state must be inactive.");
  EXPECT_CALL(*audio_track_, Stop());
}

TEST_F(MediaRecorderTest, ExceptionOnStoppingTwiceWithoutStartingInBetween) {
  scoped_refptr<script::ScriptException> exception;

  EXPECT_CALL(exception_state_, SetException(_))
      .WillOnce(SaveArg<0>(&exception));

  media_recorder_->Start(&exception_state_);
  EXPECT_CALL(*audio_track_, Stop());
  media_recorder_->Stop(&exception_state_);
  media_recorder_->Stop(&exception_state_);

  ASSERT_TRUE(exception.get());
  dom::DOMException& dom_exception(
      *base::polymorphic_downcast<dom::DOMException*>(exception.get()));
  EXPECT_EQ(dom::DOMException::kInvalidStateErr, dom_exception.code());
  EXPECT_EQ(dom_exception.message(), "Recording state must NOT be inactive.");
}

TEST_F(MediaRecorderTest, RecordL16Frames) {
  std::unique_ptr<MockEventListener> listener = MockEventListener::Create();
  FakeScriptValue<EventListener> script_object(listener.get());
  media_recorder_->set_ondataavailable(script_object);
  EXPECT_CALL(*listener,
              HandleEvent(Eq(media_recorder_),
                          Pointee(Property(&dom::Event::type,
                                           base::Tokens::dataavailable())),
                          _));

  media_recorder_->Start(&exception_state_);

  const int kSampleRate = 16000;
  media_stream::AudioParameters params(1, kSampleRate, 16);
  media_recorder_->OnSetFormat(params);

  std::vector<int16> frames;
  frames.push_back(1);
  frames.push_back(-1);
  frames.push_back(-32768);
  frames.push_back(32767);
  frames.push_back(1000);
  frames.push_back(0);
  media_stream::MediaStreamAudioTrack::ShellAudioBus audio_bus(1, frames.size(),
                                                               frames.data());
  base::TimeTicks current_time = base::TimeTicks::Now();
  media_recorder_->OnData(audio_bus, current_time);
  current_time += base::TimeDelta::FromSecondsD(frames.size() / kSampleRate);
  media_recorder_->OnData(audio_bus, current_time);
  current_time += base::TimeDelta::FromSecondsD(frames.size() / kSampleRate);
  media_recorder_->OnData(audio_bus, current_time);

  base::RunLoop().RunUntilIdle();
  EXPECT_CALL(*audio_track_, Stop());
  media_recorder_->Stop(&exception_state_);
}

TEST_F(MediaRecorderTest, DifferentThreadForAudioSource) {
  std::unique_ptr<MockEventListener> listener = MockEventListener::Create();
  FakeScriptValue<EventListener> script_object(listener.get());
  media_recorder_->set_ondataavailable(script_object);
  EXPECT_CALL(*listener,
              HandleEvent(Eq(media_recorder_),
                          Pointee(Property(&dom::Event::type,
                                           base::Tokens::dataavailable())),
                          _));

  media_recorder_->Start(&exception_state_);

  base::Thread t("MediaStrmAudio");
  t.Start();
  // media_recorder_ is a ref-counted object, binding it to PushData that will
  // later be executed on another thread violates the thread-unsafe assumption
  // of a ref-counted object; base::Bind also prohibits binding ref-counted
  // object using raw pointer. So we have to use scoped_refptr<MediaRecorder>&
  // to access media_recorder from another thread. In non-test code, accessing
  // MediaRecorder from non-javascript thread can only be done by binding its
  // member functions with base::Unretained() or weak pointer.
  // Creates media_recorder_ref just to make it clear that no copy happened
  // during base::Bind().
  t.message_loop()->task_runner()->PostBlockingTask(
      FROM_HERE,
      base::Bind(&PushData, base::Unretained(media_recorder_.get())));
  t.Stop();

  base::RunLoop().RunUntilIdle();
  EXPECT_CALL(*audio_track_, Stop());
  media_recorder_->Stop(&exception_state_);
}

TEST_F(MediaRecorderTest, StartEvent) {
  std::unique_ptr<MockEventListener> listener = MockEventListener::Create();
  FakeScriptValue<EventListener> script_object(listener.get());
  media_recorder_->set_onstart(script_object);
  EXPECT_CALL(
      *listener,
      HandleEvent(Eq(media_recorder_),
                  Pointee(Property(&dom::Event::type, base::Tokens::start())),
                  _));

  media_recorder_->Start(&exception_state_);
  EXPECT_CALL(*audio_track_, Stop());
}

TEST_F(MediaRecorderTest, StopEvent) {
  std::unique_ptr<MockEventListener> listener = MockEventListener::Create();
  FakeScriptValue<EventListener> script_object(listener.get());
  media_recorder_->Start(&exception_state_);
  media_recorder_->set_onstop(script_object);

  EXPECT_CALL(
      *listener,
      HandleEvent(Eq(media_recorder_),
                  Pointee(Property(&dom::Event::type, base::Tokens::stop())),
                  _));

  EXPECT_CALL(*audio_track_, Stop());
  media_recorder_->Stop(&exception_state_);
}

TEST_F(MediaRecorderTest, ReleaseRecorderBeforeStoppingSource) {
  // This test ensures that media recorder can be destroyed
  // before the audio source is destroyed. It should not crash.
  media_recorder_ = nullptr;
}

}  // namespace media_capture
}  // namespace cobalt
