package testutils

import (
	"fmt"

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

// NoopVolume is a volume that doesn't perform any operation
type NoopVolume struct{}

// Name is the name of the volume
func (NoopVolume) Name() string { return "noop" }

// DriverName is the name of the driver
func (NoopVolume) DriverName() string { return "noop" }

// Path is the filesystem path to the volume
func (NoopVolume) Path() string { return "noop" }

// Mount mounts the volume in the container
func (NoopVolume) Mount(_ string) (string, error) { return "noop", nil }

// Unmount unmounts the volume from the container
func (NoopVolume) Unmount(_ string) error { return nil }

// Status proivdes low-level details about the volume
func (NoopVolume) Status() map[string]interface{} { return nil }

// FakeVolume is a fake volume with a random name
type FakeVolume struct {
	name       string
	driverName string
}

// NewFakeVolume creates a new fake volume for testing
func NewFakeVolume(name string, driverName string) volume.Volume {
	return FakeVolume{name: name, driverName: driverName}
}

// Name is the name of the volume
func (f FakeVolume) Name() string { return f.name }

// DriverName is the name of the driver
func (f FakeVolume) DriverName() string { return f.driverName }

// Path is the filesystem path to the volume
func (FakeVolume) Path() string { return "fake" }

// Mount mounts the volume in the container
func (FakeVolume) Mount(_ string) (string, error) { return "fake", nil }

// Unmount unmounts the volume from the container
func (FakeVolume) Unmount(_ string) error { return nil }

// Status proivdes low-level details about the volume
func (FakeVolume) Status() map[string]interface{} { return nil }

// FakeDriver is a driver that generates fake volumes
type FakeDriver struct {
	name string
	vols map[string]volume.Volume
}

// NewFakeDriver creates a new FakeDriver with the specified name
func NewFakeDriver(name string) volume.Driver {
	return &FakeDriver{
		name: name,
		vols: make(map[string]volume.Volume),
	}
}

// Name is the name of the driver
func (d *FakeDriver) Name() string { return d.name }

// Create initializes a fake volume.
// It returns an error if the options include an "error" key with a message
func (d *FakeDriver) Create(name string, opts map[string]string) (volume.Volume, error) {
	if opts != nil && opts["error"] != "" {
		return nil, fmt.Errorf(opts["error"])
	}
	v := NewFakeVolume(name, d.name)
	d.vols[name] = v
	return v, nil
}

// Remove deletes a volume.
func (d *FakeDriver) Remove(v volume.Volume) error {
	if _, exists := d.vols[v.Name()]; !exists {
		return fmt.Errorf("no such volume")
	}
	delete(d.vols, v.Name())
	return nil
}

// List lists the volumes
func (d *FakeDriver) List() ([]volume.Volume, error) {
	var vols []volume.Volume
	for _, v := range d.vols {
		vols = append(vols, v)
	}
	return vols, nil
}

// Get gets the volume
func (d *FakeDriver) Get(name string) (volume.Volume, error) {
	if v, exists := d.vols[name]; exists {
		return v, nil
	}
	return nil, fmt.Errorf("no such volume")
}

// Scope returns the local scope
func (*FakeDriver) Scope() string {
	return "local"
}
