import {
  SQSClient,
  SendMessageCommand,
  DeleteMessageCommand,
  ReceiveMessageCommand
} from '@aws-sdk/client-sqs'
import { DeploymentPlatform, ContainerDeploymentRequest } from 'types'
import { AwsCredentialsClient } from 'aws-credentials-client'
import { logInfo, logError, logDebug } from 'log'

export class DeploymentQueueClient {

  static sendDeploymentRequest(deploymentPlatform: DeploymentPlatform, deploymentRequest: ContainerDeploymentRequest) {
    logInfo({ message: '[DeploymentQueueClient] Starting deployment sequence' })
    return DeploymentQueueClient.createAwsSqsClient(deploymentPlatform)
      .then(sqsClient => {

        const sendMessageParams = {
          QueueUrl: deploymentPlatform.awsDeploymentSqsArn,
          MessageBody: JSON.stringify(deploymentRequest)
        }

        logDebug({ message: '[DeploymentQueueClient] SendMessageCommand params', data: sendMessageParams })
        const command = new SendMessageCommand(sendMessageParams)

        return sqsClient.send(command)
          .then(() => logInfo({ message: '[DeploymentQueueClient] Deployment request sent' }))
          .catch(error => logError({ message: '[DeploymentQueueClient] Could not send deployment request', error }))
      })

  }

  static pollForDeploymentRequests(deploymentPlatform: DeploymentPlatform, handleDeploymentRequest: (deploymentRequest: ContainerDeploymentRequest) => Promise<void>) {
    logInfo({ message: '[DeploymentQueueClient] Starting polling for deployment requests' })
    DeploymentQueueClient.createAwsSqsClient(deploymentPlatform).then(sqsClient => {
      const FIVE_MINUTES = 3000

      setInterval(() => {

        const receiveMessageCommand = new ReceiveMessageCommand({ QueueUrl: deploymentPlatform.awsDeploymentSqsArn })

        sqsClient.send(receiveMessageCommand)
          .then(data => data.Messages.map(message => {

            logInfo({  message: '[DeploymentQueueClient] Received deployment request' })

            handleDeploymentRequest(JSON.parse(message.Body))
              .then(() => {

                const deleteMessageCommand = new DeleteMessageCommand({
                  QueueUrl: deploymentPlatform.awsDeploymentSqsArn,
                  ReceiptHandle: message.ReceiptHandle
                })

                sqsClient.send(deleteMessageCommand)
                  .then(() => logInfo({  message: '[DeploymentQueueClient] Removing deployment request from queue' }))
                  .catch(error => logError({  message: '[DeploymentQueueClient] Could not delete message from queue', error }))
              })

          }))
          .catch(error => logError({  message: '[ContainerManagerServer] Could not handle incoming deployment request', error }))
      }, FIVE_MINUTES)

      })
  }

  static createAwsSqsClient(deploymentPlatform: DeploymentPlatform) {
    return AwsCredentialsClient.resolveAwsCredentials(deploymentPlatform)
      .then(awsCredentials => new SQSClient({
        region: deploymentPlatform.awsRegion,
        credentials: awsCredentials
      }))
  }

}
