# frozen_string_literal: true

RSpec.describe GDK::Command::Report, :gdk_root do
  include ShelloutHelper

  let(:gdk_report) { described_class.new }
  let(:gdk_root) { Pathname.new('/home/git/gdk') }
  let(:report_template_dir) { Pathname.new('gdk/lib/support/files') }
  let(:report_template_file) { GDK.root.join(described_class::REPORT_TEMPLATE_PATH) }
  let(:args) { [] }
  let(:shellout) { double(run: true) } # rubocop:todo RSpec/VerifiedDoubles
  let(:debug_info) { GDK::Command::DebugInfo.new }

  let(:report_id) { SecureRandom.uuid }
  let(:package_manager) { 'mise-en-place' }
  let(:env_variables) { { 'PATH' => '/usr/local/bin', 'GDK_VERSION' => '0.2.0' } }
  let(:gdk_config) { { 'config' => 'value' } }
  let(:gdk_doctor) { 'GDK Doctor output' }
  let(:gem_env) { 'Gem environment' }
  let(:bundle_env) { 'Bundle environment' }
  let(:network_information) { 'Network information' }
  let(:logs) { { 'service1' => 'Log content' } }
  let(:git_status) { gdk_report.git_status('repo1') }
  let(:git_head) { gdk_report.git_head('repo1') }
  let(:git_repositories) { { 'repo1' => { git_status: git_status, git_head: git_head } } }
  let(:date_time) { Time.now.strftime('%d/%m/%Y %H:%M:%S %Z') }

  let(:report_json) do
    {
      report_id: report_id,
      os_name: debug_info.os_name,
      arch: debug_info.arch,
      ruby_version: debug_info.ruby_version,
      gdk_version: debug_info.gdk_version,
      package_manager: package_manager,
      env_variables: env_variables,
      gdk_config: gdk_config,
      gdk_doctor: gdk_doctor,
      gem_env: gem_env,
      bundle_env: bundle_env,
      network_information: network_information,
      logs: logs,
      git_repositories: git_repositories,
      date_time: date_time
    }
  end

  subject { gdk_report.run(args) }

  describe '#run' do
    before do
      allow(GDK.config.mise).to receive(:enabled?).and_return(true)
      allow(GDK.config).to receive(:gdk_root).and_return(gdk_root)
      allow(GDK.root).to receive(:join).with(described_class::REPORT_TEMPLATE_PATH)
                                       .and_return(report_template_file)

      allow(gdk_report).to receive_messages(
        report_id: report_id,
        package_manager: package_manager,
        env_variables: env_variables,
        gdk_config: gdk_config,
        gdk_doctor: gdk_doctor,
        gem_env: gem_env,
        bundle_env: bundle_env,
        network_information: network_information,
        logs: logs,
        git_repositories: git_repositories,
        git_status: { repo1: 'clean' },
        git_head: { repo1: 'commit_hash' },
        date_time: date_time
      )

      allow(GDK::Templates::ErbRenderer).to receive(:new).with(report_template_file, report_json: report_json)
        .and_call_original

      allow(gdk_report).to receive(:open_browser)
      allow(gdk_report).to receive(:copy_clipboard)
    end

    it 'displays the generated report and returns true' do
      expect_output(:info, message: 'We are collecting report details, this might take a minute ...')
      expect_output_to_include('## Environment')

      expect_output(:info, message: 'This report has been copied to your clipboard.')
      expect_output(
        :info, message: 'We opened the browser with a new issue, please paste this report from your clipboard into the description.'
      )

      expect(subject).to be(true)
    end
  end

  def expect_output(level, message: nil)
    expect(GDK::Output).to receive(level).with(message || no_args)
  end

  def expect_output_to_include(message)
    expect(GDK::Output).to receive(:puts).with(include(message))
  end
end
