# frozen_string_literal: true

require 'pathname'

require 'vagrant/action/builder'

module VagrantPlugins
  module ProfitBricks
    module Action
      # Include the built-in modules so we can use them as top-level things.
      include Vagrant::Action::Builtin

      # The autoload farm
      action_root = Pathname.new(File.expand_path('../action', __FILE__))
      autoload :ConnectProfitBricks, action_root.join('connect_profitbricks')
      autoload :CreateServer, action_root.join('create_server')
      autoload :DeleteServer, action_root.join('delete_server')
      autoload :IsCreated, action_root.join('is_created')
      autoload :MessageAlreadyCreated, action_root.join('message_already_created')
      autoload :MessageNotCreated, action_root.join('message_not_created')
      autoload :ReadSSHInfo, action_root.join('read_ssh_info')
      autoload :ReadState, action_root.join('read_state')
      autoload :RunInitScript, action_root.join('run_init_script')
      autoload :CreateImage, action_root.join('create_image')
      autoload :Stop, action_root.join('stop_server')
      autoload :ListFlavors, action_root.join('list_flavors')
      autoload :Start, action_root.join('start_server')
      autoload :ListServers, action_root.join('list_servers')
      autoload :Reboot, action_root.join('reboot_server')
      autoload :ListImages, action_root.join('list_images')

      # This action is called to destroy the remote machine.
      def self.action_destroy
        Vagrant::Action::Builder.new.tap do |b|
          b.use ConfigValidate
          b.use Call, IsCreated do |env, b1|
            unless env[:result]
              b1.use MessageNotCreated
              next
            end

            b1.use Call, DestroyConfirm do |env1, b2|
              if env1[:result]
                b2.use ConnectProfitBricks
                b2.use DeleteServer
                b2.use ProvisionerCleanup if defined?(ProvisionerCleanup)
              else
                b2.use Message, I18n.t('vagrant_profitbricks.will_not_destroy')
                next
              end
            end
          end
        end
      end

      def self.action_reload
        Vagrant::Action::Builder.new.tap do |b|
          b.use ConfigValidate
          b.use ConnectProfitBricks
          b.use Call, GetState do |env, b1|
            case env[:machine_state]
            when :active
              b1.use Reload
              b1.use Provision
            when :off
              env[:ui].info I18n.t('vagrant_profitbricks.states.long_off')
            when :not_created
              env[:ui].info I18n.t('vagrant_profitbricks.not_created')
            end
          end
        end
      end

      # This action is called when `vagrant provision` is called.
      def self.action_provision
        Vagrant::Action::Builder.new.tap do |b|
          b.use ConfigValidate
          b.use Call, IsCreated do |env, b2|
            unless env[:result]
              b2.use MessageNotCreated
              next
            end

            b2.use Provision
          end
        end
      end

      # This action is called to read the SSH info of the machine. The
      # resulting state is expected to be put into the `:machine_ssh_info`
      # key.
      def self.action_read_ssh_info
        Vagrant::Action::Builder.new.tap do |b|
          b.use ConfigValidate
          b.use ConnectProfitBricks
          b.use ReadSSHInfo
        end
      end

      # This action is called to read the state of the machine. The
      # resulting state is expected to be put into the `:machine_state_id`
      # key.
      def self.action_read_state
        Vagrant::Action::Builder.new.tap do |b|
          b.use ConfigValidate
          b.use ConnectProfitBricks
          b.use ReadState
        end
      end

      def self.action_ssh
        Vagrant::Action::Builder.new.tap do |b|
          b.use ConfigValidate
          b.use Call, IsCreated do |env, b2|
            unless env[:result]
              b2.use MessageNotCreated
              next
            end

            b2.use SSHExec
          end
        end
      end

      def self.action_ssh_run
        Vagrant::Action::Builder.new.tap do |b|
          b.use ConfigValidate
          b.use Call, IsCreated do |env, b2|
            unless env[:result]
              b2.use MessageNotCreated
              next
            end

            b2.use SSHRun
          end
        end
      end

      def self.action_up
        Vagrant::Action::Builder.new.tap do |b|
          b.use ConfigValidate
          b.use ConnectProfitBricks
          b.use Call, ReadState do |env, b2|
            if env[:result]
              b2.use MessageAlreadyCreated
              next
            end
            case env[:machine_state_id]
            when :not_created
              b2.use CreateServer
              b2.use Provision
            when :off
              b2.use Start
              b2.use Provision
            end
          end
        end
      end

      def self.action_halt
        Vagrant::Action::Builder.new.tap do |b|
          b.use Call, IsCreated do |env, b1|
            unless env[:result]
              b1.use MessageNotCreated
              next
            end

            b1.use ConfigValidate
            b1.use ConnectProfitBricks
            b1.use Stop
          end
        end
      end

      def self.action_reload
        Vagrant::Action::Builder.new.tap do |b|
          b.use Call, IsCreated do |env, b1|
            unless env[:result]
              b1.use MessageNotCreated
              next
            end
            b1.use ConfigValidate
            b1.use ConnectProfitBricks
            b1.use Reboot
          end
        end
      end

      def self.action_list_flavors
        Vagrant::Action::Builder.new.tap do |b|
          b.use ConfigValidate
          b.use ConnectProfitBricks
          b.use ListFlavors
        end
      end

      def self.action_list_images
        Vagrant::Action::Builder.new.tap do |b|
          b.use ConnectProfitBricks
          b.use ListImages
        end
      end
    end
  end
end
