// Copyright 2022 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_WORKER_EXTENDABLE_MESSAGE_EVENT_H_
#define COBALT_WORKER_EXTENDABLE_MESSAGE_EVENT_H_

#include <memory>
#include <string>
#include <utility>

#include "base/memory/scoped_refptr.h"
#include "base/optional.h"
#include "cobalt/base/token.h"
#include "cobalt/script/union_type.h"
#include "cobalt/script/value_handle.h"
#include "cobalt/script/wrappable.h"
#include "cobalt/web/event_target.h"
#include "cobalt/web/message_port.h"
#include "cobalt/worker/client.h"
#include "cobalt/worker/extendable_event.h"
#include "cobalt/worker/extendable_message_event_init.h"
#include "cobalt/worker/service_worker.h"

namespace cobalt {
namespace worker {

class ExtendableMessageEvent : public ExtendableEvent {
 public:
  using SourceType =
      cobalt::script::UnionType3<scoped_refptr<Client>,
                                 scoped_refptr<ServiceWorker>,
                                 scoped_refptr<web::MessagePort>>;

  explicit ExtendableMessageEvent(const std::string& type)
      : ExtendableEvent(type) {}
  explicit ExtendableMessageEvent(base::Token type) : ExtendableEvent(type) {}
  ExtendableMessageEvent(base::Token type,
                         std::unique_ptr<script::DataBuffer> data)
      : ExtendableEvent(type), data_(std::move(data)) {}
  ExtendableMessageEvent(const std::string& type,
                         const ExtendableMessageEventInit& init_dict);

  script::Handle<script::ValueHandle> data(
      script::EnvironmentSettings* settings = nullptr) const;

  const std::string& origin() const { return origin_; }
  const std::string& last_event_id() const { return last_event_id_; }
  const scoped_refptr<web::EventTarget>& source() const { return source_; }
  script::Sequence<scoped_refptr<MessagePort>> ports() const { return ports_; }

  // These helper functions are custom, and not in any spec.
  void set_origin(const std::string& origin) { origin_ = origin; }
  void set_last_event_id(const std::string& last_event_id) {
    last_event_id_ = last_event_id;
  }
  void set_source(const scoped_refptr<web::EventTarget>& source) {
    source_ = source;
  }
  void set_ports(script::Sequence<scoped_refptr<MessagePort>> ports) {
    ports_ = ports;
  }

  DEFINE_WRAPPABLE_TYPE(ExtendableMessageEvent);

 protected:
  ~ExtendableMessageEvent() override {}

 private:
  std::string origin_;
  std::string last_event_id_;
  scoped_refptr<web::EventTarget> source_;
  script::Sequence<scoped_refptr<MessagePort>> ports_;
  std::unique_ptr<script::DataBuffer> data_;
};

}  // namespace worker
}  // namespace cobalt

#endif  // COBALT_WORKER_EXTENDABLE_MESSAGE_EVENT_H_
