title "Cinc Workstation executables"

control "Common tests for all platforms" do
  impact 1.0
  title "Validate basic functionality on all platforms"
  desc "Common test to all platforms"

  describe command "cinc-client --version" do
    its("exit_status") { should eq 0 }
    its("stdout") { should match(/^Cinc Client:/) }
  end

  describe command "cinc-solo --version" do
    its("exit_status") { should eq 0 }
    its("stdout") { should match(/^Cinc Client:/) }
  end

  describe command "cinc-apply --version" do
    its("exit_status") { should eq 0 }
  end

  unless input("skip_known_failures")
    describe command "cinc-shell --version" do
      its("exit_status") { should eq 0 }
    end
  end

  describe command "knife --version" do
    its("exit_status") { should eq 0 }
  end

  describe command "ohai --version" do
    its("exit_status") { should eq 0 }
  end

  %w{cinc cinc-cli}.each do |cmd|
    describe command "#{cmd} --version" do
      its("exit_status") { should eq 0 }
      its("stdout") { should_not match(/[Cc]hef/) }
      its("stdout") { should match(/Cinc Workstation version:/) }
      its("stdout") { should match(/Cinc Client version:/) }
      its("stdout") { should match(/Cinc Auditor version:/) }
      its("stdout") { should match(/Cinc CLI version:/) }
      # Biome only ships an x86_64 Linux binary
      its("stdout") { should match(/Biome version:/) } unless os.linux? && os.arch == "aarch64"
      its("stdout") { should match(/Test Kitchen version:/) }
      its("stdout") { should match(/Cookstyle version:/) }
    end
  end

  describe command "kitchen --version" do
    its("exit_status") { should eq 0 }
  end

end

control "cinc-*nix" do
  impact 1.0
  title "Validate executables outputs on linux and mac"
  desc "Outputs should not contain trademarks on linux or mac"
  only_if { os.family != "windows" }

  describe command 'chef-solo -l info -o ""' do
    its("exit_status") { should eq 0 }
    its("stderr") { should match(/^Redirecting to cinc-solo/) }
    its("stdout") { should match(/Cinc Zero/) }
    its("stdout") { should match(/Cinc Client/) }
    its("stdout") { should match(/Cinc-client/) }
    # TODO: Causing issues on MacOS 12
    # its('stdout') { should match %r{/etc/cinc/client.rb} }
    its("stdout") { should match %r{/var/cinc} }
    its("stdout") { should_not match(/Chef Infra Zero/) }
    its("stdout") { should_not match(/Chef Infra Client/) }
    its("stdout") { should_not match(/Chef-client/) }
    its("stdout") { should_not match %r{/etc/chef/client.rb} }
    its("stdout") { should_not match %r{/var/chef} }
  end

  describe command "/opt/cinc-workstation/embedded/bin/cinc-zero --version" do
    its("exit_status") { should eq 0 }
  end

  describe command "/opt/cinc-workstation/bin/cinc-auditor version" do
    its("exit_status") { should eq 0 }
  end

  describe command "/opt/cinc-workstation/bin/cinc-auditor detect" do
    its("exit_status") { should eq 0 }
  end

  describe command "/opt/cinc-workstation/bin/cinc --version" do
    its("exit_status") { should eq 0 }
  end

  describe command "cinc-analyze -v" do
    # expected since this is normally used with the cinc binary
    its("exit_status") { should eq 255 }
    its("stderr") { should_not match(/[Cc]hef /) }
    its("stderr") { should match(/[Cc]inc/) }
  end

  describe command "chef-client --version" do
    its("exit_status") { should eq 0 }
    its("stderr") { should match(/Redirecting to cinc-client/) }
    its("stdout") { should match(/^Cinc Client:/) }
  end

  describe command "inspec version" do
    its("exit_status") { should eq 0 }
    its("stderr") { should match(/Redirecting to cinc-auditor/) }
    its("stdout") { should_not match(/[Ii]n[Ss]pec/) }
  end

  describe command "chef --version" do
    its("exit_status") { should eq 0 }
    its("stderr") { should match(/Redirecting to cinc/) }
    its("stdout") { should_not match(/[Cc]hef/) }
    its("stdout") { should match(/[Cc]inc/) }
  end

  describe command "chef-analyze -v" do
    its("exit_status") { should eq 255 } # expected since this is normally used with the cinc binary
    its("stderr") { should match(/Redirecting to cinc/) }
    its("stderr") { should_not match(/[Cc]hef /) }
    its("stderr") { should match(/[Cc]inc/) }
  end

  describe directory "/opt/cinc-workstation/components/chef-workstation-app" do
    it { should_not exist }
  end
end

control "inspec-resource-packs" do
  impact 1.0
  title "Bundled InSpec resource packs resolve out of the box"
  desc "Docker/Podman resources must load from the bundled resource-pack " \
       "gems with no profile dependencies, plugin install, or network. " \
       "INSPEC_CONFIG_DIR points at a scratch dir so leftover ~/.inspec " \
       "plugin or cache state cannot mask a regression."
  only_if { os.family != "windows" }

  fixture = File.expand_path("../files/resource-pack-check", __dir__)

  describe command "INSPEC_CONFIG_DIR=\"$(mktemp -d)\" /opt/cinc-workstation/bin/cinc-auditor exec #{fixture} --no-create-lockfile --no-distinct-exit" do
    its("exit_status") { should eq 0 }
    its("stdout") { should match(/4 successful/) }
    its("stdout") { should match(/0 failures/) }
    its("stdout") { should_not match(/DEPRECATION/) }
    its("stderr") { should_not match(/DEPRECATION/) }
  end
end

control "cinc-windows" do
  impact 1.0
  title "Validate executables outputs on Windows"
  desc "Outputs should not contain trademarks on Windows"
  only_if { os.family == "windows" }

  # NOTE: its('stderr') does not work properly on Windows due to https://github.com/inspec/train/issues/288

  describe command %q{cinc-solo -l info -o '""'} do
    its("exit_status") { should eq 0 }
    its("stdout") { should match(/Cinc Zero/) }
    its("stdout") { should match(/Cinc Client/) }
    its("stdout") { should match(/Cinc-client/) }
    its("stdout") { should_not match(/Chef Infra Zero/) }
    its("stdout") { should_not match(/Chef Infra Client/) }
    its("stdout") { should_not match(/Chef-client/) }
    its("stdout") { should match %r{C:/cinc/client.rb.} }
    its("stdout") { should match %r{C:/cinc} }
    its("stdout") { should_not match %r{C:/chef/client.rb} }
    its("stdout") { should_not match %r{C:/chef} }
  end

  describe command 'C:\cinc-project\cinc-workstation\embedded\bin\cinc-zero.bat --version' do
    its("exit_status") { should eq 0 }
  end

  # TODO: No -o as escaping with wrapper in inspec under windows is problematic
  # describe command %q(chef-solo -l info -o '""') do
  #   its('exit_status') { should eq 0 }
  #   its('stderr') { should match /Redirecting to cinc-solo/ }
  #   its('stdout') { should match /Cinc Zero/ }
  #   its('stdout') { should match /Cinc Client/ }
  #   its('stdout') { should match /Cinc-client/ }
  #   its('stdout') { should_not match /Chef Infra Zero/ }
  #   its('stdout') { should_not match /Chef Infra Client/ }
  #   its('stdout') { should_not match /Chef-client/ }
  #   its('stdout') { should match %r{C:/cinc/client.rb.} }
  #   its('stdout') { should match %r{C:/cinc} }
  #   its('stdout') { should_not match %r{C:/chef/client.rb} }
  #   its('stdout') { should_not match %r{C:/chef} }
  # end

  describe command "chef-client --version" do
    its("exit_status") { should eq 0 }
    # its('stderr') { should match /Redirecting to cinc-client/ }
    its("stdout") { should match(/^Cinc Client:/) }
  end

  describe command "inspec version" do
    its("exit_status") { should eq 0 }
    # its('stderr') { should match /Redirecting to cinc-auditor/ }
    its("stdout") { should_not match(/[Ii]n[Ss]pec/) }
  end

  describe command "chef --version" do
    its("exit_status") { should eq 0 }
    # its('stderr') { should match /Redirecting to cinc/ }
    its("stdout") { should_not match(/[Cc]hef/) }
    its("stdout") { should match(/[Cc]inc/) }
  end

  describe directory 'C:\cinc-project\cinc-workstation\components\chef-workstation-app' do
    it { should_not exist }
  end
end
