require 'deploy_rubygem/inspec'

module DeployRubygem
  class Cookbook
    attr_reader :cookbook_name
    attr_reader :cookbook_info

    def initialize(new_cookbook_name, new_cookbook_info)
      @cookbook_name = new_cookbook_name.to_s
      @cookbook_info = new_cookbook_info
    end

    def chef_repo
      cookbook_info[__method__]
    end

    def cookbook_path
      ::File.join(chef_repo, 'cookbooks', cookbook_name)
    end

    def git
      cookbook_info[__method__]
    end

    def groups
      cookbook_info[__method__]
    end

    def check_file
      ::File.join("#{kitchen}_check.log")
    end

    def connect_cookbook
      system("git submodule add #{git}")
      system("git submodule init cookbooks/#{cookbook_name}")
      system("git submodule sync cookbooks/#{cookbook_name}")
      system("git submodule foreach --recursive 'pwd && git pull'")
    end

    def switch_to_cookbook
      Dir.chdir(chef_repo)
      connect_cookbook
      Dir.chdir(cookbook_path)
    end

    def kitchen
      cookbook_info[:kitchens].first
    end

    def profile
      cookbook_info[:profiles].first
    end

    def kitchen_ip
      switch_to_cookbook
      system("kitchen exec #{kitchen} -c 'hostname -I'")
    end

    def kitchen_verify(showing = true)
      switch_to_cookbook
      if showing
        system("kitchen verify #{kitchen}")
      else
        system("kitchen verify #{kitchen} > #{check_file}")
      end
    end

    def kitchen_target
      kitchen_verify(false)
      system("grep -n Target #{check_file}")
    end

    def upload_cookbook
      system('git pull')

      system("chef clean-policy-cookbooks")
      # system("chef clean-policy-revisions")
    
      system("knife cookbook upload --cookbook-path '../' #{cookbook_name}")

      system("chef install Policyfile.rb")

      groups.each do |group|
        system("chef push #{group} Policyfile.lock.json")
      end
    end

    def prepare_test_environment
      cookbook_info[:profiles].each do |inspec_profile|
        profile = DeployRubygem::Inspec.new(inspec_profile)
        profile.update
      end
      system("kitchen converge #{kitchen}")
    end

    def destroy_test_environment
      system("kitchen destroy #{kitchen}")
    end

    def deploy
      save_progress
      switch_to_cookbook
      save_progress
      upload_cookbook
      prepare_test_environment
      verify
      save_progress
    end

    def verify
      puts "Verify cookbook #{cookbook_name} on target #{kitchen_target}"
      
      kitchen_verify

      cookbook_info[:execute_profiles].each do |inspec_profile|
        profile = DeployRubygem::Inspec.new(inspec_profile)
        profile.update
        profile.apply
      end
    end

    def save_progress
      system('git add .')
      system("git commit -m \"Saving: hostname=#{ENV['HOSTNAME']}, cookbook_name=#{cookbook_name}\"")
      system("git push")
    end
      
    # system('sudo chef-client --override-runlist jimbo_management_site')
  end
end