# frozen_string_literal: true

git_plugin = self

namespace :puma do
  namespace :systemd do
    desc 'Config Puma systemd service'
    task :config do
      on roles(fetch(:puma_role)) do |role|

        upload_compiled_template = lambda do |template_name, unit_filename|
          git_plugin.template_puma template_name, "#{fetch(:tmp_dir)}/#{unit_filename}", role
          systemd_path = fetch(:puma_systemd_conf_dir, git_plugin.fetch_systemd_unit_path)
          if fetch(:puma_systemctl_user) == :system
            sudo "mv #{fetch(:tmp_dir)}/#{unit_filename} #{systemd_path}"
          else
            execute :mkdir, "-p", systemd_path
            execute :mv, "#{fetch(:tmp_dir)}/#{unit_filename}", "#{systemd_path}"
          end
        end

        upload_compiled_template.call("puma.service", "#{fetch(:puma_service_unit_name)}.service")

        if fetch(:puma_enable_socket_service)
          upload_compiled_template.call("puma.socket", "#{fetch(:puma_service_unit_name)}.socket")
        end

        # Reload systemd
        git_plugin.execute_systemd("daemon-reload")
      end
    end

    desc 'Generate service configuration locally'
    task :generate_config_locally do
      fake_role = Struct.new(:hostname)
      run_locally do
        File.write('puma.service', git_plugin.compiled_template_puma("puma.service", fake_role.new("example.com")).string)
        if fetch(:puma_enable_socket_service)
          File.write('puma.socket', git_plugin.compiled_template_puma("puma.socket", fake_role.new("example.com")).string)
        end
      end
    end

    desc 'Enable Puma systemd service'
    task :enable do
      on roles(fetch(:puma_role)) do
        git_plugin.execute_systemd("enable", fetch(:puma_service_unit_name))
        git_plugin.execute_systemd("enable", fetch(:puma_service_unit_name) + ".socket") if fetch(:puma_enable_socket_service)

        if fetch(:puma_systemctl_user) != :system && fetch(:puma_enable_lingering)
          execute :loginctl, "enable-linger", fetch(:puma_lingering_user)
        end
      end
    end

    desc 'Disable Puma systemd service'
    task :disable do
      on roles(fetch(:puma_role)) do
        git_plugin.execute_systemd("disable", fetch(:puma_service_unit_name))
        git_plugin.execute_systemd("disable", fetch(:puma_service_unit_name) + ".socket") if fetch(:puma_enable_socket_service)
      end
    end

    desc 'Stop Puma socket via systemd'
    task :stop_socket do
      on roles(fetch(:puma_role)) do
        git_plugin.execute_systemd("stop", fetch(:puma_service_unit_name) + ".socket")
      end
    end

    desc 'Restart Puma socket via systemd'
    task :restart_socket do
      on roles(fetch(:puma_role)) do
        git_plugin.execute_systemd("restart", fetch(:puma_service_unit_name) + ".socket")
      end
    end
  end

  desc 'Start Puma service via systemd'
  task :start do
    on roles(fetch(:puma_role)) do
      git_plugin.execute_systemd("start", fetch(:puma_service_unit_name))
    end
  end

  desc 'Stop Puma service via systemd'
  task :stop do
    on roles(fetch(:puma_role)) do
      git_plugin.execute_systemd("stop", fetch(:puma_service_unit_name))
    end
  end

  desc 'Restart Puma service via systemd'
  task :restart do
    on roles(fetch(:puma_role)) do
      git_plugin.execute_systemd("restart", fetch(:puma_service_unit_name))
    end
  end

  desc 'Reload Puma service via systemd'
  task :reload do
    on roles(fetch(:puma_role)) do
      service_ok = if fetch(:puma_systemctl_user) == :system
        execute("#{fetch(:puma_systemctl_bin)} status #{fetch(:puma_service_unit_name)} > /dev/null", raise_on_non_zero_exit: false)
      else
        execute("#{fetch(:puma_systemctl_bin)} --user status #{fetch(:puma_service_unit_name)} > /dev/null", raise_on_non_zero_exit: false)
      end
      cmd = 'reload'
      if !service_ok
        cmd = 'restart'
      end
      if fetch(:puma_systemctl_user) == :system
        sudo "#{fetch(:puma_systemctl_bin)} #{cmd} #{fetch(:puma_service_unit_name)}"
      else
        execute "#{fetch(:puma_systemctl_bin)}", "--user", cmd, fetch(:puma_service_unit_name)
      end
    end
  end

  desc 'Get Puma service status via systemd'
  task :status do
    on roles(fetch(:puma_role)) do
      git_plugin.execute_systemd("status", fetch(:puma_service_unit_name))
      git_plugin.execute_systemd("status", fetch(:puma_service_unit_name) + ".socket") if fetch(:puma_enable_socket_service)
    end
  end
end
