package swift

import (
	"fmt"
	"strings"

	"github.com/hashicorp/terraform/internal/backend"
	"github.com/hashicorp/terraform/internal/states"
	"github.com/hashicorp/terraform/internal/states/remote"
	"github.com/hashicorp/terraform/internal/states/statemgr"
)

const (
	objectEnvPrefix = "env-"
	delimiter       = "/"
)

func (b *Backend) Workspaces() ([]string, error) {
	client := &RemoteClient{
		client:           b.client,
		container:        b.container,
		archive:          b.archive,
		archiveContainer: b.archiveContainer,
		expireSecs:       b.expireSecs,
		lockState:        b.lock,
	}

	// List our container objects
	objectNames, err := client.ListObjectsNames(objectEnvPrefix, delimiter)

	if err != nil {
		return nil, err
	}

	// Find the envs, we use a map since we can get duplicates with
	// path suffixes.
	envs := map[string]struct{}{}
	for _, object := range objectNames {
		object = strings.TrimPrefix(object, objectEnvPrefix)
		object = strings.TrimSuffix(object, delimiter)

		// Ignore objects that still contain a "/"
		// as we dont store states in subdirectories
		if idx := strings.Index(object, delimiter); idx >= 0 {
			continue
		}

		// swift is eventually consistent, thus a deleted object may
		// be listed in objectList. To ensure consistency, we query
		// each object  with a "newest" arg set to true
		payload, err := client.get(b.objectName(object))
		if err != nil {
			return nil, err
		}
		if payload == nil {
			// object doesn't exist anymore. skipping.
			continue
		}

		envs[object] = struct{}{}
	}

	result := make([]string, 1, len(envs)+1)
	result[0] = backend.DefaultStateName

	for k := range envs {
		result = append(result, k)
	}

	return result, nil
}

func (b *Backend) DeleteWorkspace(name string) error {
	if name == backend.DefaultStateName || name == "" {
		return fmt.Errorf("can't delete default state")
	}

	client := &RemoteClient{
		client:           b.client,
		container:        b.container,
		archive:          b.archive,
		archiveContainer: b.archiveContainer,
		expireSecs:       b.expireSecs,
		objectName:       b.objectName(name),
		lockState:        b.lock,
	}

	// Delete our object
	err := client.Delete()

	return err
}

func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
	if name == "" {
		return nil, fmt.Errorf("missing state name")
	}

	client := &RemoteClient{
		client:           b.client,
		container:        b.container,
		archive:          b.archive,
		archiveContainer: b.archiveContainer,
		expireSecs:       b.expireSecs,
		objectName:       b.objectName(name),
		lockState:        b.lock,
	}

	var stateMgr statemgr.Full = &remote.State{Client: client}

	// If we're not locking, disable it
	if !b.lock {
		stateMgr = &statemgr.LockDisabled{Inner: stateMgr}
	}

	// Check to see if this state already exists.
	// If we're trying to force-unlock a state, we can't take the lock before
	// fetching the state. If the state doesn't exist, we have to assume this
	// is a normal create operation, and take the lock at that point.
	//
	// If we need to force-unlock, but for some reason the state no longer
	// exists, the user will have to use openstack tools to manually fix the
	// situation.
	existing, err := b.Workspaces()
	if err != nil {
		return nil, err
	}

	exists := false
	for _, s := range existing {
		if s == name {
			exists = true
			break
		}
	}

	// We need to create the object so it's listed by States.
	if !exists {
		// the default state always exists
		if name == backend.DefaultStateName {
			return stateMgr, nil
		}

		// Grab a lock, we use this to write an empty state if one doesn't
		// exist already. We have to write an empty state as a sentinel value
		// so States() knows it exists.
		lockInfo := statemgr.NewLockInfo()
		lockInfo.Operation = "init"
		lockId, err := stateMgr.Lock(lockInfo)
		if err != nil {
			return nil, fmt.Errorf("failed to lock state in Swift: %s", err)
		}

		// Local helper function so we can call it multiple places
		lockUnlock := func(parent error) error {
			if err := stateMgr.Unlock(lockId); err != nil {
				return fmt.Errorf(strings.TrimSpace(errStateUnlock), lockId, err)
			}

			return parent
		}

		// Grab the value
		if err := stateMgr.RefreshState(); err != nil {
			err = lockUnlock(err)
			return nil, err
		}

		// If we have no state, we have to create an empty state
		if v := stateMgr.State(); v == nil {
			if err := stateMgr.WriteState(states.NewState()); err != nil {
				err = lockUnlock(err)
				return nil, err
			}
			if err := stateMgr.PersistState(); err != nil {
				err = lockUnlock(err)
				return nil, err
			}
		}

		// Unlock, the state should now be initialized
		if err := lockUnlock(nil); err != nil {
			return nil, err
		}
	}

	return stateMgr, nil
}

func (b *Backend) objectName(name string) string {
	if name != backend.DefaultStateName {
		name = fmt.Sprintf("%s%s/%s", objectEnvPrefix, name, b.stateName)
	} else {
		name = b.stateName
	}

	return name
}

const errStateUnlock = `
Error unlocking Swift state. Lock ID: %s

Error: %s

You may have to force-unlock this state in order to use it again.
The Swift backend acquires a lock during initialization to ensure
the minimum required keys are prepared.
`
