package oss

import (
	"errors"
	"fmt"
	"log"
	"path"
	"sort"
	"strings"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore"

	"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 (
	lockFileSuffix = ".tflock"
)

// get a remote client configured for this state
func (b *Backend) remoteClient(name string) (*RemoteClient, error) {
	if name == "" {
		return nil, errors.New("missing state name")
	}

	client := &RemoteClient{
		ossClient:            b.ossClient,
		bucketName:           b.bucketName,
		stateFile:            b.stateFile(name),
		lockFile:             b.lockFile(name),
		serverSideEncryption: b.serverSideEncryption,
		acl:                  b.acl,
		otsTable:             b.otsTable,
		otsClient:            b.otsClient,
	}
	if b.otsEndpoint != "" && b.otsTable != "" {
		_, err := b.otsClient.DescribeTable(&tablestore.DescribeTableRequest{
			TableName: b.otsTable,
		})
		if err != nil {
			return client, fmt.Errorf("error describing table store %s: %#v", b.otsTable, err)
		}
	}

	return client, nil
}

func (b *Backend) Workspaces() ([]string, error) {
	bucket, err := b.ossClient.Bucket(b.bucketName)
	if err != nil {
		return []string{""}, fmt.Errorf("error getting bucket: %#v", err)
	}

	var options []oss.Option
	options = append(options, oss.Prefix(b.statePrefix+"/"), oss.MaxKeys(1000))
	resp, err := bucket.ListObjects(options...)
	if err != nil {
		return nil, err
	}

	result := []string{backend.DefaultStateName}
	prefix := b.statePrefix
	lastObj := ""
	for {
		for _, obj := range resp.Objects {
			// we have 3 parts, the state prefix, the workspace name, and the state file: <prefix>/<worksapce-name>/<key>
			if path.Join(b.statePrefix, b.stateKey) == obj.Key {
				// filter the default workspace
				continue
			}
			lastObj = obj.Key
			parts := strings.Split(strings.TrimPrefix(obj.Key, prefix+"/"), "/")
			if len(parts) > 0 && parts[0] != "" {
				result = append(result, parts[0])
			}
		}
		if resp.IsTruncated {
			if len(options) == 3 {
				options[2] = oss.Marker(lastObj)
			} else {
				options = append(options, oss.Marker(lastObj))
			}
			resp, err = bucket.ListObjects(options...)
			if err != nil {
				return nil, err
			}
		} else {
			break
		}
	}
	sort.Strings(result[1:])
	return result, nil
}

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

	client, err := b.remoteClient(name)
	if err != nil {
		return err
	}
	return client.Delete()
}

func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
	client, err := b.remoteClient(name)
	if err != nil {
		return nil, err
	}
	stateMgr := &remote.State{Client: client}

	// Check to see if this state already exists.
	existing, err := b.Workspaces()
	if err != nil {
		return nil, err
	}

	log.Printf("[DEBUG] Current workspace name: %s. All workspaces:%#v", name, existing)

	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 {
		// take a lock on this state while we write it
		lockInfo := statemgr.NewLockInfo()
		lockInfo.Operation = "init"
		lockId, err := client.Lock(lockInfo)
		if err != nil {
			return nil, fmt.Errorf("failed to lock OSS state: %s", err)
		}

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

		// 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(nil); 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) stateFile(name string) string {
	if name == backend.DefaultStateName {
		return path.Join(b.statePrefix, b.stateKey)
	}
	return path.Join(b.statePrefix, name, b.stateKey)
}

func (b *Backend) lockFile(name string) string {
	return b.stateFile(name) + lockFileSuffix
}

const stateUnlockError = `
Error unlocking Alibaba Cloud OSS state file:

Lock ID: %s
Error message: %#v

You may have to force-unlock this state in order to use it again.
The Alibaba Cloud backend acquires a lock during initialization to ensure the initial state file is created.
`
