# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

# frozen_string_literal: true

# To run this demo, you will need Ruby 2.6 or later, plus dependencies.
# For more information, see:
# https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/ruby/README.md

require 'aws-sdk-lambda'
require 'aws-sdk-cloudwatchlogs'
require 'aws-sdk-iam'
require 'logger'
require 'json'
require 'zip'
require 'cli/ui'
require_relative('../../helpers/disclaimers')
require_relative('../../helpers/decorators')
require_relative('lambda_basics')
require_relative('lambda_function')

@logger = Logger.new($stdout)
@logger.level = Logger::WARN

# snippet-start:[ruby.example_code.lambda.Scenario_GettingStartedFunctions]

# Runs the scenario.
# @return [nil]
def run_scenario
  banner
  puts '######################################################################################################'.yellow
  puts '#                                                                                                    #'.yellow
  puts '#                                          EXAMPLE CODE DEMO:                                        #'.yellow
  puts '#                                             AWS Lambda                                             #'.yellow
  puts '#                                                                                                    #'.yellow
  puts '######################################################################################################'.yellow
  puts ''
  puts 'You have launched a demo of AWS Lambda using the AWS for Ruby v3 SDK. Over the next 60 seconds, it will'
  puts 'do the following:'
  puts '    1. Create a basic IAM role and policy for Lambda invocation.'
  puts '    2. Create a new Lambda function.'
  puts '    3. Invoke the Lambda function.'
  puts '    4. Update the Lambda function code.'
  puts '    5. Update the Lambda function configuration.'
  puts '    6. Destroy the Lambda function and associated IAM role.'
  puts ''

  confirm_begin
  billing
  security
  puts "\e[H\e[2J"

  source_file = 'lambda_function'
  custom_name = "lambda-function-#{rand(10**4)}"
  wrapper = LambdaWrapper.new

  new_step(1, 'Create IAM role and policy for Lambda')
  print 'Creating...'
  role, policy = wrapper.manage_iam("#{custom_name}-role", 'create')
  role_arn = role['role']['arn']
  print "Done!\n".green
  puts JSON.pretty_generate(role).green
  puts JSON.pretty_generate(policy).green
  puts '-' * 88

  new_step(2, 'Create new Lambda function')
  print "Let's create a function code to increment a number by 1..."
  if wrapper.get_function(custom_name).nil?
    print "No function exists called #{custom_name}! \nLet's create a deployment package..."
    deployment_package = wrapper.create_deployment_package(source_file)
    print "Done!\n".green if deployment_package
    print 'Uploading our deployment package to create the function...'
    response = wrapper.create_function(custom_name, "#{source_file}.lambda_handler", role_arn, deployment_package)
    print "Done!\n".green
    puts JSON.pretty_generate(response).green
  end

  new_step(3, 'List all functions')
  print "Let's do a quick list of all functions in our account..."
  response = wrapper.list_functions
  print "Done!\n".green
  puts "Discovered #{response.count} functions: #{response}"

  new_step(4, 'Invoke the function')
  response = CLI::UI::Prompt.ask('Please provide a whole number to increment by 1:')
  print "Attempting to invoke #{custom_name}..."
  payload = { number: response }
  wrapper.invoke_and_verify(custom_name, 'incremented', JSON.generate(payload))

  new_step(5, 'Update function configuration')
  print "Let's enable debugging within our function configuration..."
  response = wrapper.update_function_configuration(custom_name, 'debug')
  print "Done!\n".green if response
  puts JSON.pretty_generate(response).green
  print "Now let's invoke #{custom_name} again to see the impact of our changes..."
  wrapper.invoke_and_verify(custom_name, 'This is a debug log message')

  new_step(6, 'Update function code')
  print "Let's update our function code to multiply two whole numbers provided as invocation parameters..."
  new_deployment_package = wrapper.create_deployment_package("#{source_file}_updated")
  response = wrapper.update_function_code(custom_name, new_deployment_package)
  print "Done!\n".green if response
  puts JSON.pretty_generate(response).green
  print "Now let's invoke #{custom_name} again to see the impact of our changes...\n"
  first_number = CLI::UI::Prompt.ask('Please provide a first whole number:')
  second_number = CLI::UI::Prompt.ask('Please provide a second whole number:')
  payload = { first_number: first_number.to_i, second_number: second_number.to_i }
  wrapper.invoke_and_verify(custom_name, 'product', JSON.generate(payload))

  new_step(7, 'Delete function code')
  print "That's a wrap! Destroying IAM role and function..."
  wrapper.manage_iam("#{custom_name}-role", 'destroy')
  print "Done!\n".green
  wrapper.delete_function(custom_name)
  print "Done!\n".green
  puts '=========================================================================='.yellow
end

# snippet-end:[ruby.example_code.lambda.Scenario_GettingStartedFunctions]

run_scenario if __FILE__ == $PROGRAM_NAME
