package server

import (
        "regexp"
	"github.com/docker/go-plugins-helpers/authorization"
	"sargon/access"
	"sargon/auth"
)

type ActionAuth func (acl access.ACL, req authorization.Request) authorization.Response

type endpoint struct {
	path *regexp.Regexp
	method string
	action string
	auth ActionAuth
}

// Table of endpoints, generated from
//   https://docs.docker.com/engine/api/v1.39/swagger.yaml
var endpoints = []endpoint{
        { path: regexp.MustCompile(`^/_ping`),
          method: "GET",
          action: "SystemPing" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/auth`),
          method: "POST",
          action: "SystemAuth" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/build`),
          method: "POST",
          action: "ImageBuild" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/build/prune`),
          method: "POST",
          action: "BuildPrune" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/commit`),
          method: "POST",
          action: "ImageCommit" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/configs`),
          method: "GET",
          action: "ConfigList" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/configs/create`),
          method: "POST",
          action: "ConfigCreate" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/configs/.+?`),
          method: "DELETE",
          action: "ConfigDelete" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/configs/.+?`),
          method: "GET",
          action: "ConfigInspect" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/configs/.+?/update`),
          method: "POST",
          action: "ConfigUpdate" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/create`),
          method: "POST",
	  action: "ContainerCreate",
	  auth: auth.ContainerCreateAuth },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/json`),
          method: "GET",
          action: "ContainerList" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/prune`),
          method: "POST",
          action: "ContainerPrune" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?`),
          method: "DELETE",
          action: "ContainerDelete" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/archive`),
          method: "GET",
          action: "ContainerArchive" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/archive`),
          method: "HEAD",
          action: "ContainerArchiveInfo" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/archive`),
          method: "PUT",
          action: "PutContainerArchive" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/attach`),
          method: "POST",
          action: "ContainerAttach" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/attach/ws`),
          method: "GET",
          action: "ContainerAttachWebsocket" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/changes`),
          method: "GET",
          action: "ContainerChanges" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/exec`),
          method: "POST",
          action: "ContainerExec" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/export`),
          method: "GET",
          action: "ContainerExport" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/json`),
          method: "GET",
          action: "ContainerInspect" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/kill`),
          method: "POST",
          action: "ContainerKill" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/logs`),
          method: "GET",
          action: "ContainerLogs" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/pause`),
          method: "POST",
          action: "ContainerPause" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/rename`),
          method: "POST",
          action: "ContainerRename" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/resize`),
          method: "POST",
          action: "ContainerResize" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/restart`),
          method: "POST",
          action: "ContainerRestart" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/start`),
          method: "POST",
          action: "ContainerStart" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/stats`),
          method: "GET",
          action: "ContainerStats" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/stop`),
          method: "POST",
          action: "ContainerStop" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/top`),
          method: "GET",
          action: "ContainerTop" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/unpause`),
          method: "POST",
          action: "ContainerUnpause" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/update`),
          method: "POST",
          action: "ContainerUpdate" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/containers/.+?/wait`),
          method: "POST",
          action: "ContainerWait" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/distribution/.+?/json`),
          method: "GET",
          action: "DistributionInspect" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/events`),
          method: "GET",
          action: "SystemEvents" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/exec/.+?/json`),
          method: "GET",
          action: "ExecInspect" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/exec/.+?/resize`),
          method: "POST",
          action: "ExecResize" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/exec/.+?/start`),
          method: "POST",
          action: "ExecStart" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/images/create`),
          method: "POST",
          action: "ImageCreate" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/images/get`),
          method: "GET",
          action: "ImageGetAll" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/images/json`),
          method: "GET",
          action: "ImageList" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/images/load`),
          method: "POST",
          action: "ImageLoad" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/images/prune`),
          method: "POST",
          action: "ImagePrune" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/images/search`),
          method: "GET",
          action: "ImageSearch" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/images/.+?`),
          method: "DELETE",
          action: "ImageDelete" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/images/.+?/get`),
          method: "GET",
          action: "ImageGet" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/images/.+?/history`),
          method: "GET",
          action: "ImageHistory" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/images/.+?/json`),
          method: "GET",
          action: "ImageInspect" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/images/.+?/push`),
          method: "POST",
          action: "ImagePush" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/images/.+?/tag`),
          method: "POST",
          action: "ImageTag" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/info`),
          method: "GET",
          action: "SystemInfo" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/networks`),
          method: "GET",
          action: "NetworkList" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/networks/create`),
          method: "POST",
          action: "NetworkCreate" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/networks/prune`),
          method: "POST",
          action: "NetworkPrune" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/networks/.+?`),
          method: "DELETE",
          action: "NetworkDelete" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/networks/.+?`),
          method: "GET",
          action: "NetworkInspect" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/networks/.+?/connect`),
          method: "POST",
          action: "NetworkConnect" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/networks/.+?/disconnect`),
          method: "POST",
          action: "NetworkDisconnect" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/nodes`),
          method: "GET",
          action: "NodeList" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/nodes/.+?`),
          method: "DELETE",
          action: "NodeDelete" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/nodes/.+?`),
          method: "GET",
          action: "NodeInspect" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/nodes/.+?/update`),
          method: "POST",
          action: "NodeUpdate" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/plugins`),
          method: "GET",
          action: "PluginList" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/plugins/create`),
          method: "POST",
          action: "PluginCreate" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/plugins/privileges`),
          method: "GET",
          action: "GetPluginPrivileges" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/plugins/pull`),
          method: "POST",
          action: "PluginPull" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/plugins/.+?`),
          method: "DELETE",
          action: "PluginDelete" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/plugins/.+?/disable`),
          method: "POST",
          action: "PluginDisable" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/plugins/.+?/enable`),
          method: "POST",
          action: "PluginEnable" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/plugins/.+?/json`),
          method: "GET",
          action: "PluginInspect" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/plugins/.+?/push`),
          method: "POST",
          action: "PluginPush" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/plugins/.+?/set`),
          method: "POST",
          action: "PluginSet" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/plugins/.+?/upgrade`),
          method: "POST",
          action: "PluginUpgrade" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/secrets`),
          method: "GET",
          action: "SecretList" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/secrets/create`),
          method: "POST",
          action: "SecretCreate" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/secrets/.+?`),
          method: "DELETE",
          action: "SecretDelete" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/secrets/.+?`),
          method: "GET",
          action: "SecretInspect" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/secrets/.+?/update`),
          method: "POST",
          action: "SecretUpdate" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/services`),
          method: "GET",
          action: "ServiceList" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/services/create`),
          method: "POST",
          action: "ServiceCreate" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/services/.+?`),
          method: "DELETE",
          action: "ServiceDelete" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/services/.+?`),
          method: "GET",
          action: "ServiceInspect" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/services/.+?/logs`),
          method: "GET",
          action: "ServiceLogs" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/services/.+?/update`),
          method: "POST",
          action: "ServiceUpdate" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/session`),
          method: "POST",
          action: "Session" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/swarm`),
          method: "GET",
          action: "SwarmInspect" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/swarm/init`),
          method: "POST",
          action: "SwarmInit" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/swarm/join`),
          method: "POST",
          action: "SwarmJoin" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/swarm/leave`),
          method: "POST",
          action: "SwarmLeave" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/swarm/unlock`),
          method: "POST",
          action: "SwarmUnlock" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/swarm/unlockkey`),
          method: "GET",
          action: "SwarmUnlockkey" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/swarm/update`),
          method: "POST",
          action: "SwarmUpdate" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/system/df`),
          method: "GET",
          action: "SystemDataUsage" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/tasks`),
          method: "GET",
          action: "TaskList" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/tasks/.+?`),
          method: "GET",
          action: "TaskInspect" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/tasks/.+?/logs`),
          method: "GET",
          action: "TaskLogs" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/version`),
          method: "GET",
          action: "SystemVersion" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/volumes`),
          method: "GET",
          action: "VolumeList" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/volumes/create`),
          method: "POST",
  	  action: "VolumeCreate",
	  auth: auth.VolumeCreateAuth },
        { path: regexp.MustCompile(`^/v\d+\.\d+/volumes/prune`),
          method: "POST",
          action: "VolumePrune" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/volumes/.+?`),
          method: "DELETE",
          action: "VolumeDelete" },
        { path: regexp.MustCompile(`^/v\d+\.\d+/volumes/.+?`),
          method: "GET",
          action: "VolumeInspect" },
}

func GetAction(method, path string) (string, ActionAuth)  {
	for _, ep := range endpoints {
		if ep.method == method &&
			ep.path.FindStringSubmatch(path) != nil {
			return ep.action, ep.auth
		}
	}
	return "NONE", nil
}

