# frozen_string_literal: true

require 'fileutils'

module GDK
  module Command
    # Handles `gdk pristine` command execution
    class Pristine < BaseCommand
      BUNDLE_PRISTINE_CMD = 'bundle pristine'
      YARN_CLEAN_CMD = 'yarn clean'
      GIT_CLEAN_TMP_CMD = 'git clean -fX -- tmp/'
      RESET_CONFIGS_CMD = 'make reconfigure'

      def run(_args = [])
        %i[
          gdk_stop
          gdk_tmp_clean
          gdk_bundle
          reset_configs
          gitlab_bundle
          gitlab_tmp_clean
          gitlab_yarn_clean
        ].each do |task_name|
          run_task(task_name)
        end

        GDK::Output.success("Successfully ran 'gdk pristine'!")

        true
      rescue StandardError => e
        GDK::Output.error("Failed to run 'gdk pristine' - #{e.message}.", e)
        display_help_message

        false
      end

      def bundle_install_cmd
        "bundle install --jobs #{GDK.config.restrict_cpu_count} --quiet"
      end

      private

      def run_task(method_name)
        send(method_name) || # rubocop:disable GitlabSecurity/PublicSend
          raise("Had an issue with '#{method_name}'")
      end

      def notice(msg)
        GDK::Output.notice(msg)
      end

      def gdk_stop
        notice('Stopping GDK..')
        Runit.stop(quiet: true)
      end

      def gdk_tmp_clean
        notice('Cleaning GDK tmp/ ..')
        shellout(GIT_CLEAN_TMP_CMD)
      end

      def gdk_bundle
        notice('Ensuring GDK Ruby gems are installed and pristine..')
        gdk_bundle_install && gdk_bundle_pristine
      end

      def reset_configs
        shellout(RESET_CONFIGS_CMD)
      end

      def gdk_bundle_install
        shellout(bundle_install_cmd)
      end

      def gdk_bundle_pristine
        shellout(BUNDLE_PRISTINE_CMD)
      end

      def gitlab_bundle
        notice('Ensuring gitlab/ Ruby gems are installed and pristine..')
        gitlab_bundle_install && gitlab_bundle_pristine
      end

      def gitlab_bundle_install
        shellout(bundle_install_cmd, chdir: config.gitlab.dir)
      end

      def gitlab_bundle_pristine
        shellout(BUNDLE_PRISTINE_CMD, chdir: config.gitlab.dir)
      end

      def gitlab_yarn_clean
        notice('Cleaning gitlab/ Yarn cache..')
        shellout(YARN_CLEAN_CMD, chdir: config.gitlab.dir)
      end

      def gitlab_tmp_clean
        notice('Cleaning gitlab/tmp/ ..')
        shellout(GIT_CLEAN_TMP_CMD, chdir: config.gitlab.dir)
      end

      def shellout(cmd, **opts)
        sh = Shellout.new(cmd, **opts)
        sh.stream
        sh.success?
      rescue StandardError => e
        GDK::Output.puts(e.message, stderr: true)
        false
      end
    end
  end
end
