#
# Copyright:: Copyright (c) 2014 Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

require 'pry'
require 'spec_helper'
require 'chef-dk/command/generator_commands/base'

describe ChefDK::Command::GeneratorCommands::Base do
  describe 'parsing Chef configuration' do
    let(:cli_args) do
      [
        "-C", "Business Man",
        "-I", "Serious Business",
        "-m", "business.man@corporation.com"
      ]
    end

    before do
      Chef::Config.reset
    end

    context 'when generator configuration is defined' do
      before do
        Chef::Config.reset
        Chef::Config.chefdk.generator.copyright_holder = "This Guy"
        Chef::Config.chefdk.generator.email = "this.guy@twothumbs.net"
        Chef::Config.chefdk.generator.license = "Two Thumbs License"
      end

      it 'uses the defined values' do
        cmd = ChefDK::Command::GeneratorCommands::Base.new([])
        cmd.parse_options
        cmd.setup_context
        cfg = cmd.config
        expect(cfg[:copyright_holder]).to eq('This Guy')
        expect(cfg[:email]).to eq('this.guy@twothumbs.net')
        expect(cfg[:license]).to eq('Two Thumbs License')
      end

      context 'when cli overrides are provided' do
        before do
          Chef::Config.reset
          Chef::Config.chefdk.generator.copyright_holder = "This Guy"
          Chef::Config.chefdk.generator.email = "this.guy@twothumbs.net"
          Chef::Config.chefdk.generator.license = "Two Thumbs License"
        end

        it 'uses the cli args' do
          cmd = ChefDK::Command::GeneratorCommands::Base.new(cli_args)
          cmd.parse_options(cli_args)
          cmd.setup_context
          cfg = cmd.config
          expect(cfg[:copyright_holder]).to eq('Business Man')
          expect(cfg[:email]).to eq('business.man@corporation.com')
          expect(cfg[:license]).to eq('Serious Business')
        end
      end

      context 'when knife configuration is also defined' do

        before do
          Chef::Config.reset
          Chef::Config.chefdk.generator.copyright_holder = "This Guy"
          Chef::Config.chefdk.generator.email = "this.guy@twothumbs.net"
          Chef::Config.chefdk.generator.license = "Two Thumbs License"
          Chef::Config.knife.cookbook_copyright = "Knife User"
          Chef::Config.knife.cookbook_email = "knife.user@example.com"
          Chef::Config.knife.cookbook_license = "GPLv9000"
        end

        it 'uses the generator configuration' do
          cmd = ChefDK::Command::GeneratorCommands::Base.new([])
          cmd.parse_options
          cmd.setup_context
          cfg = cmd.config
          expect(cfg[:copyright_holder]).to eq('This Guy')
          expect(cfg[:email]).to eq('this.guy@twothumbs.net')
          expect(cfg[:license]).to eq('Two Thumbs License')
        end
      end
    end

    context 'when knife configuration is defined' do
      before do
        Chef::Config.reset
        Chef::Config.knife.cookbook_copyright = "Knife User"
        Chef::Config.knife.cookbook_email = "knife.user@example.com"
        Chef::Config.knife.cookbook_license = "GPLv9000"
      end

      it 'uses the defined values' do
        cmd = ChefDK::Command::GeneratorCommands::Base.new([])
        cmd.parse_options
        cmd.setup_context
        cfg = cmd.config
        expect(cfg[:copyright_holder]).to eq('Knife User')
        expect(cfg[:email]).to eq('knife.user@example.com')
        expect(cfg[:license]).to eq('GPLv9000')
      end

      context 'when cli overrides are provided' do

        before do
          Chef::Config.reset
          Chef::Config.knife.cookbook_copyright = "Knife User"
          Chef::Config.knife.cookbook_email = "knife.user@example.com"
          Chef::Config.knife.cookbook_license = "GPLv9000"
        end

        it 'uses the cli args' do
          cmd = ChefDK::Command::GeneratorCommands::Base.new(cli_args)
          cmd.parse_options(cli_args)
          cmd.setup_context
          cfg = cmd.config
          expect(cfg[:copyright_holder]).to eq('Business Man')
          expect(cfg[:email]).to eq('business.man@corporation.com')
          expect(cfg[:license]).to eq('Serious Business')
        end
      end
    end
  end

  describe '#have_git?' do
    let(:cmd) { described_class.new([]) }
    let(:path) { 'bin_path' }

    before do
      allow(File).to receive(:exist?)
      allow(ENV).to receive(:[]).with('PATH').and_return(path)
      allow(ENV).to receive(:[]).with('PATHEXT').and_return(nil)
      allow(RbConfig::CONFIG).to receive(:[]).with('EXEEXT').and_return('')
    end

    describe 'when git executable exists' do
      it 'returns true' do
        allow(File).to receive(:exist?).and_return(true)
        expect(cmd.have_git?).to eq(true)
      end
    end

    describe 'when git executable does not exist' do
      it 'returns false' do
        allow(File).to receive(:exist?).and_return(false)
        expect(cmd.have_git?).to eq(false)
      end
    end

    it 'checks PATH for git executable' do
      expect(File).to receive(:exist?).with(File.join(path, 'git'))
      cmd.have_git?
    end

    describe 'when on Windows' do
      before do
        allow(ENV).to receive(:[]).with('PATHEXT').and_return('.com;.exe;.bat')
        allow(RbConfig::CONFIG).to receive(:[]).with('EXEEXT').and_return('.exe')
      end

      it 'checks PATH for git executable with an extension found in PATHEXT' do
        expect(File).to receive(:exist?).with(File.join(path, 'git.com'))
        expect(File).to receive(:exist?).with(File.join(path, 'git.exe'))
        expect(File).to receive(:exist?).with(File.join(path, 'git.bat'))
        cmd.have_git?
      end
    end
  end
end