package terraform

import "path/filepath"

const (
	defaultSourceDir     = "source"
	defaultTFVarsFile    = "terraform.tfvars"
	defaultStateFile     = "terraform.tfstate"
	defaultPlanFile      = "plan.tfplan"
	defaultOutputsFile   = "outputs.json"
	defaultContractFile  = "contract.json"
	defaultLogsDir       = "logs"
	defaultPlanJSONFile  = "plan.json"
	defaultInitLogFile   = "init.log"
	defaultPlanLogFile   = "plan.log"
	defaultApplyLogFile  = "apply.log"
	defaultDestroyLog    = "destroy.log"
	dedicatedGCPModule   = "terraform/gcp/cp9-dedicated-regional"
	gcpAWSIdentityModule = "terraform/aws/cp9-gcp-runtime-identity"
)

// Paths records the Terraform workspace layout under one cp9 session.
type Paths struct {
	RootDir      string
	SourceDir    string
	TFVarsPath   string
	StatePath    string
	PlanPath     string
	OutputsPath  string
	ContractPath string
	LogsDir      string
	PlanJSONPath string
	InitLogPath  string
	PlanLogPath  string
	ApplyLogPath string
	DestroyLog   string
}

// WorkspacePaths returns the deterministic Terraform artifact layout for one session.
func WorkspacePaths(stateDir string) Paths {
	return workspacePathsAt(filepath.Join(stateDir, "terraform"))
}

// GCPWorkspacePaths keeps the optional Dedicated GCP host state independent
// from the existing primary AWS substrate state.
func GCPWorkspacePaths(stateDir string) Paths {
	paths := workspacePathsAt(filepath.Join(stateDir, "terraform-gcp"))
	paths.TFVarsPath = filepath.Join(paths.RootDir, "terraform.tfvars.json")
	return paths
}

// GCPAWSIdentityWorkspacePaths keeps the GCP runtime's AWS web-identity,
// DNS, and TLS state independent from both provider substrates.
func GCPAWSIdentityWorkspacePaths(stateDir string) Paths {
	paths := workspacePathsAt(filepath.Join(stateDir, "terraform-gcp-aws-identity"))
	paths.TFVarsPath = filepath.Join(paths.RootDir, "terraform.tfvars.json")
	return paths
}

// DedicatedGCPModulePath returns the one CP9-owned module used by plan and
// status output; it is not a user-configurable source path.
func DedicatedGCPModulePath(repo string) string {
	return filepath.Join(repo, DedicatedGCPModule())
}

// DedicatedGCPModule returns the repository-relative source path copied into
// each session workspace before plan/apply.
func DedicatedGCPModule() string { return dedicatedGCPModule }

// DedicatedGCPAWSIdentityModule returns the repository-relative AWS identity
// root materialized for the optional GCP runtime.
func DedicatedGCPAWSIdentityModule() string { return gcpAWSIdentityModule }

func workspacePathsAt(root string) Paths {
	logs := filepath.Join(root, defaultLogsDir)
	return Paths{
		RootDir:      root,
		SourceDir:    filepath.Join(root, defaultSourceDir),
		TFVarsPath:   filepath.Join(root, defaultTFVarsFile),
		StatePath:    filepath.Join(root, defaultStateFile),
		PlanPath:     filepath.Join(root, defaultPlanFile),
		OutputsPath:  filepath.Join(root, defaultOutputsFile),
		ContractPath: filepath.Join(root, defaultContractFile),
		LogsDir:      logs,
		PlanJSONPath: filepath.Join(logs, defaultPlanJSONFile),
		InitLogPath:  filepath.Join(logs, defaultInitLogFile),
		PlanLogPath:  filepath.Join(logs, defaultPlanLogFile),
		ApplyLogPath: filepath.Join(logs, defaultApplyLogFile),
		DestroyLog:   filepath.Join(logs, defaultDestroyLog),
	}
}

// WorkspacePathsForVarFile returns workspace paths whose TFVarsPath is the
// mutable session-local copy of the persona-owned .tfvars file.
func WorkspacePathsForVarFile(stateDir, varFile string) Paths {
	paths := WorkspacePaths(stateDir)
	if base := filepath.Base(varFile); base != "." && base != string(filepath.Separator) && base != "" {
		paths.TFVarsPath = filepath.Join(paths.RootDir, base)
	}
	return paths
}
