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

#ifndef COBALT_H5VCC_H5VCC_EVENT_LISTENER_CONTAINER_H_
#define COBALT_H5VCC_H5VCC_EVENT_LISTENER_CONTAINER_H_

#include <string>
#include <vector>

#include "base/callback.h"
#include "base/location.h"
#include "base/message_loop_proxy.h"
#include "base/synchronization/lock.h"
#include "cobalt/script/callback_function.h"
#include "cobalt/script/script_value.h"
#include "cobalt/script/wrappable.h"

namespace cobalt {
namespace h5vcc {

// Template class to implement a container of event listeners where the
// listener callback can take an argument of any type, including none (void).
// Callback type must be specified in addition to callback argument type,
// as we cannot typedef a callback taking a void argument.
template <class CallbackArgType, class CallbackType>
class H5vccEventListenerContainer {
 public:
  typedef script::ScriptValue<CallbackType> CallbackHolderType;

  // Type for a callback that returns the value of the argument to be passed
  // to the callback for each listener.
  typedef base::Callback<CallbackArgType()> GetArgumentCallback;

  // Type for a listener.
  // We store the message loop from which the listener was registered,
  // so we can run the callback on the same loop.
  struct Listener {
    Listener(script::Wrappable* owner, const CallbackHolderType& cb)
        : callback(owner, cb),
          message_loop(base::MessageLoopProxy::current()) {}

    // Notifies listener. Must be called on the same message loop the
    // listener registered its callback from.
    void Notify(GetArgumentCallback on_notify) {
      DCHECK_EQ(base::MessageLoopProxy::current(), message_loop);
      CallbackArgType arg = on_notify.Run();
      callback.value().Run(arg);
    }

    typename CallbackHolderType::Reference callback;
    scoped_refptr<base::MessageLoopProxy> message_loop;
  };

  explicit H5vccEventListenerContainer(script::Wrappable* owner)
      : owner_(owner) {}

  ~H5vccEventListenerContainer() {
    // Delete all registered listeners.
    for (typename ListenerVector::const_iterator it = listeners_.begin();
         it != listeners_.end(); ++it) {
      delete *it;
    }
  }

  // Called from JavaScript to register an event listener. May be called from
  // any thread, and event notification will be called on the same thread.
  void AddListener(const CallbackHolderType& callback_holder) {
    base::AutoLock auto_lock(lock_);
    listeners_.push_back(new Listener(owner_, callback_holder));
  }

  // Dispatches an event to the registered listeners. May be called from any
  // thread, and the callbacks will be invoked on the same thread each listener
  // was registered on. |get_argument_callback| must be a function that
  // returns the argument value for this event.
  void DispatchEvent(GetArgumentCallback get_argument_callback) {
    base::AutoLock auto_lock(lock_);
    for (typename ListenerVector::iterator it = listeners_.begin();
         it != listeners_.end(); ++it) {
      Listener* listener = *it;
      listener->message_loop->PostTask(
          FROM_HERE, base::Bind(&Listener::Notify, base::Unretained(listener),
                                get_argument_callback));
    }
  }

 private:
  typedef std::vector<Listener*> ListenerVector;

  script::Wrappable* owner_;
  ListenerVector listeners_;
  base::Lock lock_;
};

// Explicit template specialization for the no callback argument case, where
// we don't need to call the |GetArgumentCallback| callback.
template <>
inline void
    H5vccEventListenerContainer<void, script::CallbackFunction<void()> >::
        Listener::Notify(GetArgumentCallback) {
  DCHECK_EQ(base::MessageLoopProxy::current(), message_loop);
  callback.value().Run();
}

}  // namespace h5vcc
}  // namespace cobalt

#endif  // COBALT_H5VCC_H5VCC_EVENT_LISTENER_CONTAINER_H_
