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

#ifndef COBALT_MEDIA_CAPTURE_MEDIA_RECORDER_H_
#define COBALT_MEDIA_CAPTURE_MEDIA_RECORDER_H_

#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop_proxy.h"
#include "base/optional.h"
#include "base/string_piece.h"
#include "base/threading/thread_checker.h"
#include "base/time.h"
#include "cobalt/dom/blob_property_bag.h"
#include "cobalt/dom/event_target.h"
#include "cobalt/media_capture/encoders/audio_encoder.h"
#include "cobalt/media_capture/media_recorder_options.h"
#include "cobalt/media_capture/recording_state.h"
#include "cobalt/media_stream/audio_parameters.h"
#include "cobalt/media_stream/media_stream.h"
#include "cobalt/media_stream/media_stream_audio_sink.h"
#include "cobalt/script/environment_settings.h"
#include "cobalt/script/exception_state.h"
#include "cobalt/script/wrappable.h"

namespace cobalt {
namespace media_capture {

// This class represents a MediaRecorder, and implements the specification at:
// https://www.w3.org/TR/mediastream-recording/#mediarecorder-api
class MediaRecorder : public media_stream::MediaStreamAudioSink,
                      public encoders::AudioEncoder::Listener,
                      public dom::EventTarget {
 public:
  // Constructors.
  explicit MediaRecorder(script::EnvironmentSettings* settings,
                         const scoped_refptr<media_stream::MediaStream>& stream,
                         script::ExceptionState* exception_state);

  explicit MediaRecorder(script::EnvironmentSettings* settings,
                         const scoped_refptr<media_stream::MediaStream>& stream,
                         const MediaRecorderOptions& options,
                         script::ExceptionState* exception_state);

  ~MediaRecorder() override;

  // Readonly attributes.
  const std::string& mime_type() const { return mime_type_; }

  // Functions
  static bool IsTypeSupported(const base::StringPiece mime_type);

  void Start(int32 timeslice, script::ExceptionState* exception_state);

  void Start(script::ExceptionState* exception_state) {
    Start(kint32max, exception_state);
  }

  void Stop(script::ExceptionState* exception_state);

  // EventHandlers.
  const EventListenerScriptValue* onstart() const {
    DCHECK(thread_checker_.CalledOnValidThread());
    return GetAttributeEventListener(base::Tokens::start());
  }

  void set_onstart(const EventListenerScriptValue& event_listener) {
    DCHECK(thread_checker_.CalledOnValidThread());
    SetAttributeEventListener(base::Tokens::start(), event_listener);
  }

  const EventListenerScriptValue* onstop() const {
    DCHECK(thread_checker_.CalledOnValidThread());
    return GetAttributeEventListener(base::Tokens::stop());
  }

  void set_onstop(const EventListenerScriptValue& event_listener) {
    DCHECK(thread_checker_.CalledOnValidThread());
    SetAttributeEventListener(base::Tokens::stop(), event_listener);
  }

  const EventListenerScriptValue* onerror() const {
    DCHECK(thread_checker_.CalledOnValidThread());
    return GetAttributeEventListener(base::Tokens::error());
  }

  void set_onerror(const EventListenerScriptValue& event_listener) {
    DCHECK(thread_checker_.CalledOnValidThread());
    SetAttributeEventListener(base::Tokens::error(), event_listener);
  }

  const EventListenerScriptValue* ondataavailable() const {
    DCHECK(thread_checker_.CalledOnValidThread());
    return GetAttributeEventListener(base::Tokens::dataavailable());
  }

  void set_ondataavailable(const EventListenerScriptValue& event_listener) {
    DCHECK(thread_checker_.CalledOnValidThread());
    SetAttributeEventListener(base::Tokens::dataavailable(), event_listener);
  }

  RecordingState state() { return recording_state_; }

  // MediaStreamAudioSink overrides.
  void OnData(const ShellAudioBus& audio_bus,
              base::TimeTicks reference_time) override;
  void OnSetFormat(const media_stream::AudioParameters& params) override;
  void OnReadyStateChanged(
      media_stream::MediaStreamTrack::ReadyState ready_state) override;

  DEFINE_WRAPPABLE_TYPE(MediaRecorder);

 private:
  MediaRecorder(const MediaRecorder&) = delete;
  MediaRecorder& operator=(const MediaRecorder&) = delete;

  void StopRecording();

  void UnsubscribeFromTrack();

  void DoOnDataCallback(base::TimeTicks timecode);
  void OnEncodedDataAvailable(const uint8* data, size_t data_size,
                              base::TimeTicks timecode) override;
  void WriteData(scoped_ptr<std::vector<uint8>> data, bool last_in_slice,
                 base::TimeTicks timecode);
  void CalculateLastInSliceAndWriteData(scoped_ptr<std::vector<uint8>> data,
                                        base::TimeTicks timecode);

  base::ThreadChecker thread_checker_;

  // |audio_encoder_| lives on the microphone thread.
  scoped_ptr<encoders::AudioEncoder> audio_encoder_;
  std::vector<uint8> buffer_;

  RecordingState recording_state_ = kRecordingStateInactive;

  script::EnvironmentSettings* settings_;
  std::string mime_type_;
  dom::BlobPropertyBag blob_options_;
  scoped_refptr<media_stream::MediaStream> stream_;

  scoped_refptr<base::MessageLoopProxy> javascript_message_loop_;
  base::TimeDelta timeslice_;
  // Only used to determine if |timeslice_| amount of time has
  // been passed since the slice was started.
  base::TimeTicks slice_origin_timestamp_;

  base::WeakPtrFactory<MediaRecorder> weak_ptr_factory_;
  base::WeakPtr<MediaRecorder> weak_this_;
};

}  // namespace media_capture
}  // namespace cobalt

#endif  // COBALT_MEDIA_CAPTURE_MEDIA_RECORDER_H_
