package v3appdeployers

import (
	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
	"code.cloudfoundry.org/cli/resources"
)

// ScaleApplicationProcess : scale application web processes (instances, memory, diskquota)
func (a Actor) ScaleApplicationProcess(appDeploy AppDeploy, reverse FallbackFunction) Action {
	return Action{
		Forward: func(ctx Context) (Context, error) {
			appResp := ctx["app_response"].(AppDeployResponse)

			// Action code
			processScaleInfo := resources.Process{
				Type:      constant.ProcessTypeWeb,
				Instances: appDeploy.Process.Instances,
			}

			if appDeploy.Process.MemoryInMB.IsSet && appDeploy.Process.MemoryInMB.Value > 0 {
				processScaleInfo.MemoryInMB = appDeploy.Process.MemoryInMB
			}

			if appDeploy.Process.DiskInMB.IsSet && appDeploy.Process.DiskInMB.Value > 0 {
				processScaleInfo.DiskInMB = appDeploy.Process.DiskInMB
			}

			scaledProcess, _, err := a.client.CreateApplicationProcessScale(appResp.App.GUID, processScaleInfo)
			if err != nil {
				return ctx, err
			}

			appResp.Process = scaledProcess

			ctx["app_response"] = appResp
			return ctx, nil
		},
		ReversePrevious: reverse,
	}
}

// UpdateApplicationProcess : update application processes information
func (a Actor) UpdateApplicationProcess(appDeploy AppDeploy, reverse FallbackFunction) Action {
	return Action{
		Forward: func(ctx Context) (Context, error) {
			appResp := ctx["app_response"].(AppDeployResponse)

			// Action code

			process, _, err := a.client.GetApplicationProcessByType(appResp.App.GUID, constant.ProcessTypeWeb)
			if err != nil {
				return ctx, err
			}

			updatedProcess, _, err := a.client.UpdateProcess(resources.Process{
				GUID:                         process.GUID,
				Command:                      appDeploy.Process.Command,
				HealthCheckType:              appDeploy.Process.HealthCheckType,
				HealthCheckEndpoint:          appDeploy.Process.HealthCheckEndpoint,
				HealthCheckTimeout:           appDeploy.Process.HealthCheckTimeout,
				HealthCheckInvocationTimeout: appDeploy.Process.HealthCheckInvocationTimeout,
			})
			if err != nil {
				return ctx, err
			}
			// If command = null or "", the command field in updatedProcess will be the default generated by buildpack
			// In that case, we don't set it in tfstate
			if !appDeploy.Process.Command.IsSet {
				updatedProcess.Command = appDeploy.Process.Command
			}

			appResp.Process = updatedProcess

			ctx["app_response"] = appResp
			return ctx, nil
		},
		ReversePrevious: reverse,
	}
}
