package authorization // import "github.com/docker/docker/pkg/authorization"

import (
	"sync"

	"github.com/docker/docker/pkg/plugingetter"
	"github.com/docker/docker/pkg/plugins"
)

// Plugin allows third party plugins to authorize requests and responses
// in the context of docker API
type Plugin interface {
	// Name returns the registered plugin name
	Name() string

	// AuthZRequest authorizes the request from the client to the daemon
	AuthZRequest(*Request) (*Response, error)

	// AuthZResponse authorizes the response from the daemon to the client
	AuthZResponse(*Request) (*Response, error)
}

// newPlugins constructs and initializes the authorization plugins based on plugin names
func newPlugins(names []string) []Plugin {
	plugins := []Plugin{}
	pluginsMap := make(map[string]struct{})
	for _, name := range names {
		if _, ok := pluginsMap[name]; ok {
			continue
		}
		pluginsMap[name] = struct{}{}
		plugins = append(plugins, newAuthorizationPlugin(name))
	}
	return plugins
}

var getter plugingetter.PluginGetter

// SetPluginGetter sets the plugingetter
func SetPluginGetter(pg plugingetter.PluginGetter) {
	getter = pg
}

// GetPluginGetter gets the plugingetter
func GetPluginGetter() plugingetter.PluginGetter {
	return getter
}

// authorizationPlugin is an internal adapter to docker plugin system
type authorizationPlugin struct {
	initErr error
	plugin  *plugins.Client
	name    string
	once    sync.Once
}

func newAuthorizationPlugin(name string) Plugin {
	return &authorizationPlugin{name: name}
}

func (a *authorizationPlugin) Name() string {
	return a.name
}

// Set the remote for an authz pluginv2
func (a *authorizationPlugin) SetName(remote string) {
	a.name = remote
}

func (a *authorizationPlugin) AuthZRequest(authReq *Request) (*Response, error) {
	if err := a.initPlugin(); err != nil {
		return nil, err
	}

	authRes := &Response{}
	if err := a.plugin.Call(AuthZApiRequest, authReq, authRes); err != nil {
		return nil, err
	}

	return authRes, nil
}

func (a *authorizationPlugin) AuthZResponse(authReq *Request) (*Response, error) {
	if err := a.initPlugin(); err != nil {
		return nil, err
	}

	authRes := &Response{}
	if err := a.plugin.Call(AuthZApiResponse, authReq, authRes); err != nil {
		return nil, err
	}

	return authRes, nil
}

// initPlugin initializes the authorization plugin if needed
func (a *authorizationPlugin) initPlugin() error {
	// Lazy loading of plugins
	a.once.Do(func() {
		if a.plugin == nil {
			var plugin plugingetter.CompatPlugin
			var e error

			if pg := GetPluginGetter(); pg != nil {
				plugin, e = pg.Get(a.name, AuthZApiImplements, plugingetter.Lookup)
				a.SetName(plugin.Name())
			} else {
				plugin, e = plugins.Get(a.name, AuthZApiImplements)
			}
			if e != nil {
				a.initErr = e
				return
			}
			a.plugin = plugin.Client()
		}
	})
	return a.initErr
}
