package manager

// RevertSecretInput represents the input of a RevertSecret operation
type RevertSecretInput struct {
	Name       string
	Version    int64
	ActionUser string
}

// RevertSecretOutput represents the output of a RevertSecret operation
type RevertSecretOutput struct{}

func (input *RevertSecretInput) validate() (err error) {
	if input.Name == "" {
		err = &InputValidationError{"invalid input, Secret name cannot be empty"}
	} else if input.Version <= 0 {
		err = &InputValidationError{"invalid input, secret version cannot be <= 0"}
	}
	return
}

// RevertSecret reverts the given secret to the version specified.
func (m *Manager) RevertSecret(input *RevertSecretInput) (out *RevertSecretOutput, err error) {

	err = m.statter.WithMeasuredResult("secret.revert", nil, func() (err error) {
		err = input.validate()
		if err != nil {
			return
		}
		var oldSecret *Secret
		oldSecret, err = m.Get(input.Name)
		if err != nil {
			return
		}
		if oldSecret == nil {
			err = ErrSecretDoesNotExist
			return
		}

		var secret *Secret
		secret, err = m.getVersion(input.Name, input.Version)
		if err != nil {
			return
		}
		if secret == nil {
			err = ErrorSecretVersionDoesNotExist
			return
		}

		if input.ActionUser != "" {
			secret.ActionUser = input.ActionUser
		}

		err = m.putItem(secret, false)
		if err != nil {
			return
		}

		// Set the version of secret that was current before revert.
		err = m.setPreviousVersion(secret, oldSecret.UpdatedAt)
		return
	})
	return
}

// Revert will revert a key to a previous value
// This will *not* append to the audit table
func (m *Manager) Revert(name string, version int64) (err error) {

	input := &RevertSecretInput{
		Name:       name,
		Version:    version,
		ActionUser: m.Config.ActionUser,
	}
	_, err = m.RevertSecret(input)
	return
}
