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

import (
	"errors"
	"strings"
	"time"

	"github.com/docker/docker/volume"
	"github.com/sirupsen/logrus"
)

var (
	errNoSuchVolume = errors.New("no such volume")
)

type volumeDriverAdapter struct {
	name         string
	scopePath    func(s string) string
	capabilities *volume.Capability
	proxy        volumeDriver
}

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

func (a *volumeDriverAdapter) Create(name string, opts map[string]string) (volume.Volume, error) {
	if err := a.proxy.Create(name, opts); err != nil {
		return nil, err
	}
	return &volumeAdapter{
		proxy:      a.proxy,
		name:       name,
		driverName: a.name,
		scopePath:  a.scopePath,
	}, nil
}

func (a *volumeDriverAdapter) Remove(v volume.Volume) error {
	return a.proxy.Remove(v.Name())
}

func (a *volumeDriverAdapter) List() ([]volume.Volume, error) {
	ls, err := a.proxy.List()
	if err != nil {
		return nil, err
	}

	var out []volume.Volume
	for _, vp := range ls {
		out = append(out, &volumeAdapter{
			proxy:      a.proxy,
			name:       vp.Name,
			scopePath:  a.scopePath,
			driverName: a.name,
			eMount:     a.scopePath(vp.Mountpoint),
		})
	}
	return out, nil
}

func (a *volumeDriverAdapter) Get(name string) (volume.Volume, error) {
	v, err := a.proxy.Get(name)
	if err != nil {
		return nil, err
	}

	// plugin may have returned no volume and no error
	if v == nil {
		return nil, errNoSuchVolume
	}

	return &volumeAdapter{
		proxy:      a.proxy,
		name:       v.Name,
		driverName: a.Name(),
		eMount:     v.Mountpoint,
		createdAt:  v.CreatedAt,
		status:     v.Status,
		scopePath:  a.scopePath,
	}, nil
}

func (a *volumeDriverAdapter) Scope() string {
	cap := a.getCapabilities()
	return cap.Scope
}

func (a *volumeDriverAdapter) getCapabilities() volume.Capability {
	if a.capabilities != nil {
		return *a.capabilities
	}
	cap, err := a.proxy.Capabilities()
	if err != nil {
		// `GetCapabilities` is a not a required endpoint.
		// On error assume it's a local-only driver
		logrus.WithError(err).WithField("driver", a.name).Debug("Volume driver returned an error while trying to query its capabilities, using default capabilities")
		return volume.Capability{Scope: volume.LocalScope}
	}

	// don't spam the warn log below just because the plugin didn't provide a scope
	if len(cap.Scope) == 0 {
		cap.Scope = volume.LocalScope
	}

	cap.Scope = strings.ToLower(cap.Scope)
	if cap.Scope != volume.LocalScope && cap.Scope != volume.GlobalScope {
		logrus.WithField("driver", a.Name()).WithField("scope", a.Scope).Warn("Volume driver returned an invalid scope")
		cap.Scope = volume.LocalScope
	}

	a.capabilities = &cap
	return cap
}

type volumeAdapter struct {
	proxy      volumeDriver
	name       string
	scopePath  func(string) string
	driverName string
	eMount     string    // ephemeral host volume path
	createdAt  time.Time // time the directory was created
	status     map[string]interface{}
}

type proxyVolume struct {
	Name       string
	Mountpoint string
	CreatedAt  time.Time
	Status     map[string]interface{}
}

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

func (a *volumeAdapter) DriverName() string {
	return a.driverName
}

func (a *volumeAdapter) Path() string {
	if len(a.eMount) == 0 {
		mountpoint, _ := a.proxy.Path(a.name)
		a.eMount = a.scopePath(mountpoint)
	}
	return a.eMount
}

func (a *volumeAdapter) CachedPath() string {
	return a.eMount
}

func (a *volumeAdapter) Mount(id string) (string, error) {
	mountpoint, err := a.proxy.Mount(a.name, id)
	a.eMount = a.scopePath(mountpoint)
	return a.eMount, err
}

func (a *volumeAdapter) Unmount(id string) error {
	err := a.proxy.Unmount(a.name, id)
	if err == nil {
		a.eMount = ""
	}
	return err
}

func (a *volumeAdapter) CreatedAt() (time.Time, error) {
	return a.createdAt, nil
}
func (a *volumeAdapter) Status() map[string]interface{} {
	out := make(map[string]interface{}, len(a.status))
	for k, v := range a.status {
		out[k] = v
	}
	return out
}
