@tool
class_name TwitchEvents
extends Object

enum Event {
	AUTOMOD_MESSAGE_HOLD,
	AUTOMOD_MESSAGE_UPDATE,
	AUTOMOD_SETTINGS_UPDATE,
	AUTOMOD_TERMS_UPDATE,
	CHANNEL_UPDATE,
	CHANNEL_FOLLOW,
	CHANNEL_AD_BREAK_BEGIN,
	CHANNEL_CHAT_CLEAR,
	CHANNEL_CHAT_CLEAR_USER_MESSAGES,
	CHANNEL_CHAT_MESSAGE,
	CHANNEL_CHAT_MESSAGE_DELETE,
	CHANNEL_CHAT_NOTIFICATION,
	CHANNEL_CHAT_SETTINGS_UPDATE,
	CHANNEL_CHAT_USER_MESSAGE_HOLD,
	CHANNEL_CHAT_USER_MESSAGE_UPDATE,
	CHANNEL_SUBSCRIBE,
	CHANNEL_SUBSCRIPTION_END,
	CHANNEL_SUBSCRIPTION_GIFT,
	CHANNEL_SUBSCRIPTION_MESSAGE,
	CHANNEL_CHEER,
	CHANNEL_RAID,
	CHANNEL_BAN,
	CHANNEL_UNBAN,
	CHANNEL_UNBAN_REQUEST_CREATE,
	CHANNEL_UNBAN_REQUEST_RESOLVE,
	CHANNEL_MODERATE,
	CHANNEL_MODERATOR_ADD,
	CHANNEL_MODERATOR_REMOVE,
	CHANNEL_GUEST_STAR_SESSION_BEGIN,
	CHANNEL_GUEST_STAR_SESSION_END,
	CHANNEL_GUEST_STAR_GUEST_UPDATE,
	CHANNEL_GUEST_STAR_SETTINGS_UPDATE,
	CHANNEL_CHANNEL_POINTS_AUTOMATIC_REWARD_REDEMPTION_ADD,
	CHANNEL_CHANNEL_POINTS_CUSTOM_REWARD_ADD,
	CHANNEL_CHANNEL_POINTS_CUSTOM_REWARD_UPDATE,
	CHANNEL_CHANNEL_POINTS_CUSTOM_REWARD_REMOVE,
	CHANNEL_CHANNEL_POINTS_CUSTOM_REWARD_REDEMPTION_ADD,
	CHANNEL_CHANNEL_POINTS_CUSTOM_REWARD_REDEMPTION_UPDATE,
	CHANNEL_POLL_BEGIN,
	CHANNEL_POLL_PROGRESS,
	CHANNEL_POLL_END,
	CHANNEL_PREDICTION_BEGIN,
	CHANNEL_PREDICTION_PROGRESS,
	CHANNEL_PREDICTION_LOCK,
	CHANNEL_PREDICTION_END,
	CHANNEL_SUSPICIOUS_USER_MESSAGE,
	CHANNEL_SUSPICIOUS_USER_UPDATE,
	CHANNEL_VIP_ADD,
	CHANNEL_VIP_REMOVE,
	CHANNEL_CHARITY_CAMPAIGN_DONATE,
	CHANNEL_CHARITY_CAMPAIGN_START,
	CHANNEL_CHARITY_CAMPAIGN_PROGRESS,
	CHANNEL_CHARITY_CAMPAIGN_STOP,
	CONDUIT_SHARD_DISABLED,
	DROP_ENTITLEMENT_GRANT,
	EXTENSION_BITS_TRANSACTION_CREATE,
	CHANNEL_GOAL_BEGIN,
	CHANNEL_GOAL_PROGRESS,
	CHANNEL_GOAL_END,
	CHANNEL_HYPE_TRAIN_BEGIN,
	CHANNEL_HYPE_TRAIN_PROGRESS,
	CHANNEL_HYPE_TRAIN_END,
	CHANNEL_SHIELD_MODE_BEGIN,
	CHANNEL_SHIELD_MODE_END,
	CHANNEL_SHOUTOUT_CREATE,
	CHANNEL_SHOUTOUT_RECEIVE,
	STREAM_ONLINE,
	STREAM_OFFLINE,
	USER_AUTHORIZATION_GRANT,
	USER_AUTHORIZATION_REVOKE,
	USER_UPDATE,
	USER_WHISPER_RECEIVED
}

static var _events = [
	EventInfo.new(Event.AUTOMOD_MESSAGE_HOLD, "automod.message.hold", "1"),
	EventInfo.new(Event.AUTOMOD_MESSAGE_UPDATE, "automod.message.update", "1"),
	EventInfo.new(Event.AUTOMOD_SETTINGS_UPDATE, "automod.settings.update", "1"),
	EventInfo.new(Event.AUTOMOD_TERMS_UPDATE, "automod.terms.update", "1"),
	EventInfo.new(Event.CHANNEL_UPDATE, "channel.update", "2"),
	EventInfo.new(Event.CHANNEL_FOLLOW, "channel.follow", "2"),
	EventInfo.new(Event.CHANNEL_AD_BREAK_BEGIN, "channel.ad_break.begin", "1"),
	EventInfo.new(Event.CHANNEL_CHAT_CLEAR, "channel.chat.clear", "1"),
	EventInfo.new(Event.CHANNEL_CHAT_CLEAR_USER_MESSAGES, "channel.chat.clear_user_messages", "1"),
	EventInfo.new(Event.CHANNEL_CHAT_MESSAGE, "channel.chat.message", "1"),
	EventInfo.new(Event.CHANNEL_CHAT_MESSAGE_DELETE, "channel.chat.message_delete", "1"),
	EventInfo.new(Event.CHANNEL_CHAT_NOTIFICATION, "channel.chat.notification", "1"),
	EventInfo.new(Event.CHANNEL_CHAT_SETTINGS_UPDATE, "channel.chat_settings.update", "1"),
	EventInfo.new(Event.CHANNEL_CHAT_USER_MESSAGE_HOLD, "channel.chat.user_message_hold", "1"),
	EventInfo.new(Event.CHANNEL_CHAT_USER_MESSAGE_UPDATE, "channel.chat.user_message_update", "1"),
	EventInfo.new(Event.CHANNEL_SUBSCRIBE, "channel.subscribe", "1"),
	EventInfo.new(Event.CHANNEL_SUBSCRIPTION_END, "channel.subscription.end", "1"),
	EventInfo.new(Event.CHANNEL_SUBSCRIPTION_GIFT, "channel.subscription.gift", "1"),
	EventInfo.new(Event.CHANNEL_SUBSCRIPTION_MESSAGE, "channel.subscription.message", "1"),
	EventInfo.new(Event.CHANNEL_CHEER, "channel.cheer", "1"),
	EventInfo.new(Event.CHANNEL_RAID, "channel.raid", "1"),
	EventInfo.new(Event.CHANNEL_BAN, "channel.ban", "1"),
	EventInfo.new(Event.CHANNEL_UNBAN, "channel.unban", "1"),
	EventInfo.new(Event.CHANNEL_UNBAN_REQUEST_CREATE, "channel.unban_request.create", "1"),
	EventInfo.new(Event.CHANNEL_UNBAN_REQUEST_RESOLVE, "channel.unban_request.resolve", "1"),
	EventInfo.new(Event.CHANNEL_MODERATE, "channel.moderate", "1"),
	EventInfo.new(Event.CHANNEL_MODERATOR_ADD, "channel.moderator.add", "1"),
	EventInfo.new(Event.CHANNEL_MODERATOR_REMOVE, "channel.moderator.remove", "1"),
	EventInfo.new(Event.CHANNEL_GUEST_STAR_SESSION_BEGIN, "channel.guest_star_session.begin", "beta"),
	EventInfo.new(Event.CHANNEL_GUEST_STAR_SESSION_END, "channel.guest_star_session.end", "beta"),
	EventInfo.new(Event.CHANNEL_GUEST_STAR_GUEST_UPDATE, "channel.guest_star_guest.update", "beta"),
	EventInfo.new(Event.CHANNEL_GUEST_STAR_SETTINGS_UPDATE, "channel.guest_star_settings.update", "beta"),
	EventInfo.new(Event.CHANNEL_CHANNEL_POINTS_AUTOMATIC_REWARD_REDEMPTION_ADD, "channel.channel_points_automatic_reward_redemption.add", "1"),
	EventInfo.new(Event.CHANNEL_CHANNEL_POINTS_CUSTOM_REWARD_ADD, "channel.channel_points_custom_reward.add", "1"),
	EventInfo.new(Event.CHANNEL_CHANNEL_POINTS_CUSTOM_REWARD_UPDATE, "channel.channel_points_custom_reward.update", "1"),
	EventInfo.new(Event.CHANNEL_CHANNEL_POINTS_CUSTOM_REWARD_REMOVE, "channel.channel_points_custom_reward.remove", "1"),
	EventInfo.new(Event.CHANNEL_CHANNEL_POINTS_CUSTOM_REWARD_REDEMPTION_ADD, "channel.channel_points_custom_reward_redemption.add", "1"),
	EventInfo.new(Event.CHANNEL_CHANNEL_POINTS_CUSTOM_REWARD_REDEMPTION_UPDATE, "channel.channel_points_custom_reward_redemption.update", "1"),
	EventInfo.new(Event.CHANNEL_POLL_BEGIN, "channel.poll.begin", "1"),
	EventInfo.new(Event.CHANNEL_POLL_PROGRESS, "channel.poll.progress", "1"),
	EventInfo.new(Event.CHANNEL_POLL_END, "channel.poll.end", "1"),
	EventInfo.new(Event.CHANNEL_PREDICTION_BEGIN, "channel.prediction.begin", "1"),
	EventInfo.new(Event.CHANNEL_PREDICTION_PROGRESS, "channel.prediction.progress", "1"),
	EventInfo.new(Event.CHANNEL_PREDICTION_LOCK, "channel.prediction.lock", "1"),
	EventInfo.new(Event.CHANNEL_PREDICTION_END, "channel.prediction.end", "1"),
	EventInfo.new(Event.CHANNEL_SUSPICIOUS_USER_MESSAGE, "channel.suspicious_user.message", "1"),
	EventInfo.new(Event.CHANNEL_SUSPICIOUS_USER_UPDATE, "channel.suspicious_user.update", "1"),
	EventInfo.new(Event.CHANNEL_VIP_ADD, "channel.vip.add", "1"),
	EventInfo.new(Event.CHANNEL_VIP_REMOVE, "channel.vip.remove", "1"),
	EventInfo.new(Event.CHANNEL_CHARITY_CAMPAIGN_DONATE, "channel.charity_campaign.donate", "1"),
	EventInfo.new(Event.CHANNEL_CHARITY_CAMPAIGN_START, "channel.charity_campaign.start", "1"),
	EventInfo.new(Event.CHANNEL_CHARITY_CAMPAIGN_PROGRESS, "channel.charity_campaign.progress", "1"),
	EventInfo.new(Event.CHANNEL_CHARITY_CAMPAIGN_STOP, "channel.charity_campaign.stop", "1"),
	EventInfo.new(Event.CONDUIT_SHARD_DISABLED, "conduit.shard.disabled", "1"),
	EventInfo.new(Event.DROP_ENTITLEMENT_GRANT, "drop.entitlement.grant", "1"),
	EventInfo.new(Event.EXTENSION_BITS_TRANSACTION_CREATE, "extension.bits_transaction.create", "1"),
	EventInfo.new(Event.CHANNEL_GOAL_BEGIN, "channel.goal.begin", "1"),
	EventInfo.new(Event.CHANNEL_GOAL_PROGRESS, "channel.goal.progress", "1"),
	EventInfo.new(Event.CHANNEL_GOAL_END, "channel.goal.end", "1"),
	EventInfo.new(Event.CHANNEL_HYPE_TRAIN_BEGIN, "channel.hype_train.begin", "1"),
	EventInfo.new(Event.CHANNEL_HYPE_TRAIN_PROGRESS, "channel.hype_train.progress", "1"),
	EventInfo.new(Event.CHANNEL_HYPE_TRAIN_END, "channel.hype_train.end", "1"),
	EventInfo.new(Event.CHANNEL_SHIELD_MODE_BEGIN, "channel.shield_mode.begin", "1"),
	EventInfo.new(Event.CHANNEL_SHIELD_MODE_END, "channel.shield_mode.end", "1"),
	EventInfo.new(Event.CHANNEL_SHOUTOUT_CREATE, "channel.shoutout.create", "1"),
	EventInfo.new(Event.CHANNEL_SHOUTOUT_RECEIVE, "channel.shoutout.receive", "1"),
	EventInfo.new(Event.STREAM_ONLINE, "stream.online", "1"),
	EventInfo.new(Event.STREAM_OFFLINE, "stream.offline", "1"),
	EventInfo.new(Event.USER_AUTHORIZATION_GRANT, "user.authorization.grant", "1"),
	EventInfo.new(Event.USER_AUTHORIZATION_REVOKE, "user.authorization.revoke", "1"),
	EventInfo.new(Event.USER_UPDATE, "user.update", "1"),
	EventInfo.new(Event.USER_WHISPER_RECEIVED, "user.whisper.message", "1")
]


# -- Public Methods


static func get_event_from_type(type: Event):
	var result = _events.filter(func(event): return event.type == type)
	
	if result:
		return result[0]
	else:
		return null


static func get_event_from_name(name: String):
	var result = _events.filter(func(event): return event.name == name)
	
	if result:
		return result[0]
	else:
		return null


static func get_event_type_from_name(name: String):
	var result = _events.filter(func(event): return event.name == name)
	
	if result:
		return result[0].type
	else:
		return null


# -- Classes


class EventInfo:
	var type: Event
	var name: String
	var version: String
	var conditions: Array[String]
	
	
	func _init(type: Event, name: String, version: String, conditions: Array[String] = []):
		self.type = type
		self.name = name
		self.version = version
		self.conditions = conditions
	
	
	func generate_sub(arguments: Dictionary):
		return {
			"type": self.name,
			"version": self.version,
			"condition": { # Change to generalize for all types
				"broadcaster_user_id": arguments.broadcaster,
				"user_id": arguments.user
			},
			"transport": {
				"method": "websocket",
				"session_id": arguments.websocket
			}
		}