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

import (
	"context"
	"sync/atomic"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/filters"
	"github.com/docker/docker/errdefs"
	"github.com/docker/docker/pkg/directory"
	"github.com/docker/docker/pkg/idtools"
	"github.com/docker/docker/pkg/plugingetter"
	"github.com/docker/docker/pkg/stringid"
	"github.com/docker/docker/volume"
	"github.com/docker/docker/volume/drivers"
	"github.com/docker/docker/volume/service/opts"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

type ds interface {
	GetDriverList() []string
}

type volumeEventLogger interface {
	LogVolumeEvent(volumeID, action string, attributes map[string]string)
}

// VolumesService manages access to volumes
type VolumesService struct {
	vs           *VolumeStore
	ds           ds
	pruneRunning int32
	eventLogger  volumeEventLogger
}

// NewVolumeService creates a new volume service
func NewVolumeService(root string, pg plugingetter.PluginGetter, rootIDs idtools.IDPair, logger volumeEventLogger) (*VolumesService, error) {
	ds := drivers.NewStore(pg)
	if err := setupDefaultDriver(ds, root, rootIDs); err != nil {
		return nil, err
	}

	vs, err := NewStore(root, ds)
	if err != nil {
		return nil, err
	}
	return &VolumesService{vs: vs, ds: ds, eventLogger: logger}, nil
}

// GetDriverList gets the list of registered volume drivers
func (s *VolumesService) GetDriverList() []string {
	return s.ds.GetDriverList()
}

// Create creates a volume
func (s *VolumesService) Create(ctx context.Context, name, driverName string, opts ...opts.CreateOption) (*types.Volume, error) {
	if name == "" {
		name = stringid.GenerateNonCryptoID()
	}
	v, err := s.vs.Create(ctx, name, driverName, opts...)
	if err != nil {
		return nil, err
	}

	s.eventLogger.LogVolumeEvent(v.Name(), "create", map[string]string{"driver": v.DriverName()})
	apiV := volumeToAPIType(v)
	return &apiV, nil
}

// Get gets a volume
func (s *VolumesService) Get(ctx context.Context, name string, getOpts ...opts.GetOption) (*types.Volume, error) {
	v, err := s.vs.Get(ctx, name, getOpts...)
	if err != nil {
		return nil, err
	}
	vol := volumeToAPIType(v)

	var cfg opts.GetConfig
	for _, o := range getOpts {
		o(&cfg)
	}

	if cfg.ResolveStatus {
		vol.Status = v.Status()
	}
	return &vol, nil
}

// Mount mounts the volume
func (s *VolumesService) Mount(ctx context.Context, vol *types.Volume, ref string) (string, error) {
	v, err := s.vs.Get(ctx, vol.Name, opts.WithGetDriver(vol.Driver))
	if err != nil {
		if IsNotExist(err) {
			err = errdefs.NotFound(err)
		}
		return "", err
	}
	return v.Mount(ref)
}

// Unmount unmounts the volume.
// Note that depending on the implementation, the volume may still be mounted due to other resources using it.
func (s *VolumesService) Unmount(ctx context.Context, vol *types.Volume, ref string) error {
	v, err := s.vs.Get(ctx, vol.Name, opts.WithGetDriver(vol.Driver))
	if err != nil {
		if IsNotExist(err) {
			err = errdefs.NotFound(err)
		}
		return err
	}
	return v.Unmount(ref)
}

// Release releases a volume reference
func (s *VolumesService) Release(ctx context.Context, name string, ref string) error {
	return s.vs.Release(ctx, name, ref)
}

// Remove removes a volume
func (s *VolumesService) Remove(ctx context.Context, name string, rmOpts ...opts.RemoveOption) error {
	var cfg opts.RemoveConfig
	for _, o := range rmOpts {
		o(&cfg)
	}

	v, err := s.vs.Get(ctx, name)
	if err != nil {
		if IsNotExist(err) && cfg.PurgeOnError {
			return nil
		}
		return err
	}

	err = s.vs.Remove(ctx, v, rmOpts...)
	if IsNotExist(err) {
		err = nil
	} else if IsInUse(err) {
		err = errdefs.Conflict(err)
	} else if IsNotExist(err) && cfg.PurgeOnError {
		err = nil
	}

	if err == nil {
		s.eventLogger.LogVolumeEvent(v.Name(), "destroy", map[string]string{"driver": v.DriverName()})
	}
	return err
}

var acceptedPruneFilters = map[string]bool{
	"label":  true,
	"label!": true,
}

var acceptedListFilters = map[string]bool{
	"dangling": true,
	"name":     true,
	"driver":   true,
	"label":    true,
}

// LocalVolumesSize gets all local volumes and fetches their size on disk
// Note that this intentionally skips volumes which have mount options. Typically
// volumes with mount options are not really local even if they are using the
// local driver.
func (s *VolumesService) LocalVolumesSize(ctx context.Context) ([]*types.Volume, error) {
	ls, _, err := s.vs.Find(ctx, And(ByDriver(volume.DefaultDriverName), CustomFilter(func(v volume.Volume) bool {
		dv, ok := v.(volume.DetailedVolume)
		return ok && len(dv.Options()) == 0
	})))
	if err != nil {
		return nil, err
	}
	return s.volumesToAPI(ctx, ls, calcSize(true)), nil
}

// Prune removes (local) volumes which match the past in filter arguments.
// Note that this intentionally skips volumes with mount options as there would
// be no space reclaimed in this case.
func (s *VolumesService) Prune(ctx context.Context, filter filters.Args) (*types.VolumesPruneReport, error) {
	if !atomic.CompareAndSwapInt32(&s.pruneRunning, 0, 1) {
		return nil, errdefs.Conflict(errors.New("a prune operation is already running"))
	}
	defer atomic.StoreInt32(&s.pruneRunning, 0)

	by, err := filtersToBy(filter, acceptedPruneFilters)
	if err != nil {
		return nil, err
	}
	ls, _, err := s.vs.Find(ctx, And(ByDriver(volume.DefaultDriverName), ByReferenced(false), by, CustomFilter(func(v volume.Volume) bool {
		dv, ok := v.(volume.DetailedVolume)
		return ok && len(dv.Options()) == 0
	})))
	if err != nil {
		return nil, err
	}

	rep := &types.VolumesPruneReport{VolumesDeleted: make([]string, 0, len(ls))}
	for _, v := range ls {
		select {
		case <-ctx.Done():
			err := ctx.Err()
			if err == context.Canceled {
				err = nil
			}
			return rep, err
		default:
		}

		vSize, err := directory.Size(ctx, v.Path())
		if err != nil {
			logrus.WithField("volume", v.Name()).WithError(err).Warn("could not determine size of volume")
		}
		if err := s.vs.Remove(ctx, v); err != nil {
			logrus.WithError(err).WithField("volume", v.Name()).Warnf("Could not determine size of volume")
			continue
		}
		rep.SpaceReclaimed += uint64(vSize)
		rep.VolumesDeleted = append(rep.VolumesDeleted, v.Name())
	}
	return rep, nil
}

// List gets the list of volumes which match the past in filters
// If filters is nil or empty all volumes are returned.
func (s *VolumesService) List(ctx context.Context, filter filters.Args) (volumesOut []*types.Volume, warnings []string, err error) {
	by, err := filtersToBy(filter, acceptedListFilters)
	if err != nil {
		return nil, nil, err
	}

	volumes, warnings, err := s.vs.Find(ctx, by)
	if err != nil {
		return nil, nil, err
	}

	return s.volumesToAPI(ctx, volumes, useCachedPath(true)), warnings, nil
}

// Shutdown shuts down the image service and dependencies
func (s *VolumesService) Shutdown() error {
	return s.vs.Shutdown()
}
