//go:generate pluginrpc-gen -i $GOFILE -o proxy.go -type volumeDriver -name VolumeDriver

package drivers // import "github.com/docker/docker/volume/drivers"

import (
	"fmt"
	"sort"
	"sync"

	"github.com/docker/docker/errdefs"
	"github.com/docker/docker/pkg/locker"
	getter "github.com/docker/docker/pkg/plugingetter"
	"github.com/docker/docker/pkg/plugins"
	"github.com/docker/docker/volume"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

const extName = "VolumeDriver"

// volumeDriver defines the available functions that volume plugins must implement.
// This interface is only defined to generate the proxy objects.
// It's not intended to be public or reused.
// nolint: deadcode
type volumeDriver interface {
	// Create a volume with the given name
	Create(name string, opts map[string]string) (err error)
	// Remove the volume with the given name
	Remove(name string) (err error)
	// Get the mountpoint of the given volume
	Path(name string) (mountpoint string, err error)
	// Mount the given volume and return the mountpoint
	Mount(name, id string) (mountpoint string, err error)
	// Unmount the given volume
	Unmount(name, id string) (err error)
	// List lists all the volumes known to the driver
	List() (volumes []*proxyVolume, err error)
	// Get retrieves the volume with the requested name
	Get(name string) (volume *proxyVolume, err error)
	// Capabilities gets the list of capabilities of the driver
	Capabilities() (capabilities volume.Capability, err error)
}

// Store is an in-memory store for volume drivers
type Store struct {
	extensions   map[string]volume.Driver
	mu           sync.Mutex
	driverLock   *locker.Locker
	pluginGetter getter.PluginGetter
}

// NewStore creates a new volume driver store
func NewStore(pg getter.PluginGetter) *Store {
	return &Store{
		extensions:   make(map[string]volume.Driver),
		driverLock:   locker.New(),
		pluginGetter: pg,
	}
}

type driverNotFoundError string

func (e driverNotFoundError) Error() string {
	return "volume driver not found: " + string(e)
}

func (driverNotFoundError) NotFound() {}

// lookup returns the driver associated with the given name. If a
// driver with the given name has not been registered it checks if
// there is a VolumeDriver plugin available with the given name.
func (s *Store) lookup(name string, mode int) (volume.Driver, error) {
	if name == "" {
		return nil, errdefs.InvalidParameter(errors.New("driver name cannot be empty"))
	}
	s.driverLock.Lock(name)
	defer s.driverLock.Unlock(name)

	s.mu.Lock()
	ext, ok := s.extensions[name]
	s.mu.Unlock()
	if ok {
		return ext, nil
	}
	if s.pluginGetter != nil {
		p, err := s.pluginGetter.Get(name, extName, mode)
		if err != nil {
			return nil, errors.Wrap(err, "error looking up volume plugin "+name)
		}

		d, err := makePluginAdapter(p)
		if err != nil {
			return nil, errors.Wrap(err, "error making plugin client")
		}
		if err := validateDriver(d); err != nil {
			if mode > 0 {
				// Undo any reference count changes from the initial `Get`
				if _, err := s.pluginGetter.Get(name, extName, mode*-1); err != nil {
					logrus.WithError(err).WithField("action", "validate-driver").WithField("plugin", name).Error("error releasing reference to plugin")
				}
			}
			return nil, err
		}

		if p.IsV1() {
			s.mu.Lock()
			s.extensions[name] = d
			s.mu.Unlock()
		}
		return d, nil
	}
	return nil, driverNotFoundError(name)
}

func validateDriver(vd volume.Driver) error {
	scope := vd.Scope()
	if scope != volume.LocalScope && scope != volume.GlobalScope {
		return fmt.Errorf("Driver %q provided an invalid capability scope: %s", vd.Name(), scope)
	}
	return nil
}

// Register associates the given driver to the given name, checking if
// the name is already associated
func (s *Store) Register(d volume.Driver, name string) bool {
	if name == "" {
		return false
	}

	s.mu.Lock()
	defer s.mu.Unlock()

	if _, exists := s.extensions[name]; exists {
		return false
	}

	if err := validateDriver(d); err != nil {
		return false
	}

	s.extensions[name] = d
	return true
}

// GetDriver returns a volume driver by its name.
// If the driver is empty, it looks for the local driver.
func (s *Store) GetDriver(name string) (volume.Driver, error) {
	return s.lookup(name, getter.Lookup)
}

// CreateDriver returns a volume driver by its name and increments RefCount.
// If the driver is empty, it looks for the local driver.
func (s *Store) CreateDriver(name string) (volume.Driver, error) {
	return s.lookup(name, getter.Acquire)
}

// ReleaseDriver returns a volume driver by its name and decrements RefCount..
// If the driver is empty, it looks for the local driver.
func (s *Store) ReleaseDriver(name string) (volume.Driver, error) {
	return s.lookup(name, getter.Release)
}

// GetDriverList returns list of volume drivers registered.
// If no driver is registered, empty string list will be returned.
func (s *Store) GetDriverList() []string {
	var driverList []string
	s.mu.Lock()
	defer s.mu.Unlock()
	for driverName := range s.extensions {
		driverList = append(driverList, driverName)
	}
	sort.Strings(driverList)
	return driverList
}

// GetAllDrivers lists all the registered drivers
func (s *Store) GetAllDrivers() ([]volume.Driver, error) {
	var plugins []getter.CompatPlugin
	if s.pluginGetter != nil {
		var err error
		plugins, err = s.pluginGetter.GetAllByCap(extName)
		if err != nil {
			return nil, fmt.Errorf("error listing plugins: %v", err)
		}
	}
	var ds []volume.Driver

	s.mu.Lock()
	defer s.mu.Unlock()

	for _, d := range s.extensions {
		ds = append(ds, d)
	}

	for _, p := range plugins {
		name := p.Name()

		if _, ok := s.extensions[name]; ok {
			continue
		}

		ext, err := makePluginAdapter(p)
		if err != nil {
			return nil, errors.Wrap(err, "error making plugin client")
		}
		if p.IsV1() {
			s.extensions[name] = ext
		}
		ds = append(ds, ext)
	}
	return ds, nil
}

func makePluginAdapter(p getter.CompatPlugin) (*volumeDriverAdapter, error) {
	if pc, ok := p.(getter.PluginWithV1Client); ok {
		return &volumeDriverAdapter{name: p.Name(), scopePath: p.ScopedPath, proxy: &volumeDriverProxy{pc.Client()}}, nil
	}

	pa, ok := p.(getter.PluginAddr)
	if !ok {
		return nil, errdefs.System(errors.Errorf("got unknown plugin instance %T", p))
	}

	if pa.Protocol() != plugins.ProtocolSchemeHTTPV1 {
		return nil, errors.Errorf("plugin protocol not supported: %s", p)
	}

	addr := pa.Addr()
	client, err := plugins.NewClientWithTimeout(addr.Network()+"://"+addr.String(), nil, pa.Timeout())
	if err != nil {
		return nil, errors.Wrap(err, "error creating plugin client")
	}

	return &volumeDriverAdapter{name: p.Name(), scopePath: p.ScopedPath, proxy: &volumeDriverProxy{client}}, nil
}
