#include "DOMExceptionBinding.h"
#include "DOMMatrixBinding.h"
#include "DOMPointBinding.h"
#include "DOMQuadBinding.h"
#include "DOMRectBinding.h"
#include "FileSystemDirectoryHandleBinding.h"
#include "FileSystemFileHandleBinding.h"
#include "FileSystemHandleBinding.h"
#include "ImageDataBinding.h"
#include "StructuredCloneTesterBinding.h"
#include "SubtleCryptoBinding.h"
#include "mozilla/PerfectHash.h"
#include "mozilla/dom/WebIDLSerializable.h"

namespace mozilla::dom {
struct WebIDLSerializableEntry {
  StructuredCloneTags mTag;
  WebIDLDeserializer mDeserialize;
  uint16_t mExposedGlobals;
};

static const WebIDLSerializableEntry sEntries[] = {
  {
    /* mTag */ SCTAG_DOM_CRYPTOKEY,
    /* mDeserialize */ CryptoKey_Binding::Deserialize,
    /* mExposedGlobals */ GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::Window,
  },
  {
    /* mTag */ SCTAG_DOM_DOMEXCEPTION,
    /* mDeserialize */ DOMException_Binding::Deserialize,
    /* mExposedGlobals */ GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::Window,
  },
  {
    /* mTag */ SCTAG_DOM_DOMMATRIX,
    /* mDeserialize */ DOMMatrix_Binding::Deserialize,
    /* mExposedGlobals */ GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::Window,
  },
  {
    /* mTag */ SCTAG_DOM_DOMMATRIXREADONLY,
    /* mDeserialize */ DOMMatrixReadOnly_Binding::Deserialize,
    /* mExposedGlobals */ GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::Window,
  },
  {
    /* mTag */ SCTAG_DOM_DOMPOINT,
    /* mDeserialize */ DOMPoint_Binding::Deserialize,
    /* mExposedGlobals */ GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::Window,
  },
  {
    /* mTag */ SCTAG_DOM_DOMPOINTREADONLY,
    /* mDeserialize */ DOMPointReadOnly_Binding::Deserialize,
    /* mExposedGlobals */ GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::Window,
  },
  {
    /* mTag */ SCTAG_DOM_DOMQUAD,
    /* mDeserialize */ DOMQuad_Binding::Deserialize,
    /* mExposedGlobals */ GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::Window,
  },
  {
    /* mTag */ SCTAG_DOM_DOMRECT,
    /* mDeserialize */ DOMRect_Binding::Deserialize,
    /* mExposedGlobals */ GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::Window,
  },
  {
    /* mTag */ SCTAG_DOM_DOMRECTREADONLY,
    /* mDeserialize */ DOMRectReadOnly_Binding::Deserialize,
    /* mExposedGlobals */ GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::Window,
  },
  {
    /* mTag */ SCTAG_DOM_FILESYSTEMDIRECTORYHANDLE,
    /* mDeserialize */ FileSystemDirectoryHandle_Binding::Deserialize,
    /* mExposedGlobals */ GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::Window,
  },
  {
    /* mTag */ SCTAG_DOM_FILESYSTEMFILEHANDLE,
    /* mDeserialize */ FileSystemFileHandle_Binding::Deserialize,
    /* mExposedGlobals */ GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::Window,
  },
  {
    /* mTag */ SCTAG_DOM_FILESYSTEMHANDLE,
    /* mDeserialize */ FileSystemHandle_Binding::Deserialize,
    /* mExposedGlobals */ GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::Window,
  },
  {
    /* mTag */ SCTAG_DOM_IMAGEDATA,
    /* mDeserialize */ ImageData_Binding::Deserialize,
    /* mExposedGlobals */ GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::Window,
  },
  {
    /* mTag */ SCTAG_DOM_STRUCTUREDCLONETESTER,
    /* mDeserialize */ StructuredCloneTester_Binding::Deserialize,
    /* mExposedGlobals */ GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::Window,
  }
};

Maybe<std::pair<uint16_t, WebIDLDeserializer>> LookupDeserializer(StructuredCloneTags aTag) {
  for (auto& entry : sEntries) {
    if (entry.mTag == aTag) {
      return Some(std::pair(entry.mExposedGlobals, entry.mDeserialize));
    }
  }
  return Nothing();
}
} // namespace mozilla::dom

