class Raykit::Project

def branch

def branch
  return "main" if @git_directory.nil?
  @git_directory.branch
end

def commit(commit_message)

def commit(commit_message)
  warn "[DEPRECATION] 'commit_message_filename' is deprecated. Use a run command for better transparency."
  Dir.chdir(@directory) do
    if File.exist?(".gitignore")
      status = `git status`
      if status.include?("Changes not staged for commit:")
        run("git add --all")
        if GIT_DIRECTORY.outstanding_commit?
          if File.exist?(@commit_message_filename)
            run("git commit --file #{@commit_message_filename}")
            File.delete(@commit_message_filename)
          else
            run("git commit -m'#{commit_message}'")
          end
        end
      end
    else
      puts "warning: .gitignore not found."
    end
  end
  self
end

def commit_message_filename

def commit_message_filename
  warn "[DEPRECATION] 'commit_message_filename' is deprectated."
  @commit_message_filename
end

def detached?

def detached?
  return true if @git_directory.nil?
  @git_directory.detached?
end

def elapsed

def elapsed
  elapsed = @timer.elapsed
  if elapsed < 1.0
    "#{format("%.1f", @timer.elapsed)}s"
  else
    "#{format("%.0f", @timer.elapsed)}s"
  end
end

def get_dev_dir(subdir)

def get_dev_dir(subdir)
  Raykit::Environment.get_dev_dir(subdir)
end

def get_markdown_nvp(key, value, pad_char)

def get_markdown_nvp(key, value, pad_char)
  "\n| " + key.to_s.ljust(36, pad_char) + "| " + value.to_s.ljust(36, pad_char)
end

def has_diff?(filename)

def has_diff?(filename)
  Dir.chdir(@directory) do
    text = `git diff #{filename}`.strip
    return true if text.length.positive?
  end
end

def info

def info
  ljust = 35
  puts ""
  puts "PROJECT.name".ljust(ljust) + Rainbow(PROJECT.name).yellow.bright
  puts "PROJECT.version".ljust(ljust) + Rainbow(PROJECT.version).yellow.bright
  puts "PROJECT.remote".ljust(ljust) + Rainbow(PROJECT.remote).yellow.bright
  puts "PROJECT.branch".ljust(ljust) + Rainbow(PROJECT.branch).yellow.bright
  puts "PROJECT.detached?".ljust(ljust) + Rainbow(PROJECT.detached?).yellow.bright
  # puts "PROJECT.target".ljust(ljust) + Rainbow(PROJECT.target).yellow.bright

  # puts "PROJECT.target_md5".ljust(ljust) + Rainbow(PROJECT.target_md5).yellow.bright

  puts "PROJECT.latest_tag".ljust(ljust) + Rainbow(PROJECT.latest_tag).yellow.bright
  puts "PROJECT.latest_tag_commit".ljust(ljust) + Rainbow(PROJECT.latest_tag_commit).yellow.bright
  puts "PROJECT.latest_tag_md5".ljust(ljust) + Rainbow(PROJECT.latest_tag_md5).yellow.bright
  puts "PROJECT.latest_commit".ljust(ljust) + Rainbow(PROJECT.latest_commit).yellow.bright
  puts "PROJECT.last_modified_filename".ljust(ljust) + Rainbow(PROJECT.last_modified_filename).yellow.bright
  # puts "PROJECT.elapsed".ljust(ljust) + Rainbow(PROJECT.elapsed).yellow.bright

  puts "PROJECT.size".ljust(ljust) + Rainbow(PROJECT.size).yellow.bright
  puts "PROJECT.size_pack".ljust(ljust) + Rainbow(PROJECT.size_pack).yellow.bright
  puts "PROJECT.outstanding_commit?".ljust(ljust) + Rainbow(PROJECT.outstanding_commit?).yellow.bright
  puts "PROJECT.outstanding_tag?".ljust(ljust) + Rainbow(PROJECT.outstanding_tag?).yellow.bright
  puts ""
  self
end

def initialize

def initialize
  @timeout = 1000 * 60 * 15
  @verbose = false
  @timer = Raykit::Timer.new
  @remote = ""
  @commit_message_filename = "commit_message.tmp"
  if Dir.exist?(RAKE_DIRECTORY)
    @directory = RAKE_DIRECTORY
    if Dir.exist?("#{RAKE_DIRECTORY}/.git") && Dir.exist?(@directory)
      @git_directory = Raykit::Git::Directory.new(@directory)
      @remote = @git_directory.remote
    end
  else
    @directory = ""
  end
  # @log=Log.new("#{RAKE_DIRECTORY}/tmp/raykit.log")

  if defined?(NAME)
    @name = NAME
  else
    slns = Dir.glob("*.sln")
    if slns.length == 1
      @name = slns[0].gsub(".sln", "")
    else
      gemspecs = Dir.glob("*.gemspec")
      if gemspecs.length == 1
        @name = gemspecs[0].gsub(".gemspec", "")
      else
        remote_parts = @remote.split("/")
        @name = remote_parts[-1].gsub(".git", "") if remote_parts.length.positive?
      end
    end
  end
  @repository = Raykit::Git::Repository.new(@remote)
  @values = Hash::new()
  @commands = Array::new()
end

def last_modified_filename

def last_modified_filename
  Dir.chdir(@directory) do
    Dir.glob("**/*.*").select { |f| File.file?(f) }.max_by { |f| File.mtime(f) }
  end
end

def latest_commit

latest local commit
def latest_commit
  return "" if detached?
  Dir.chdir(@directory) do
    text = `git log -n 1`
    scan = text.scan(/commit (\w+)\s/)
    return scan[0][0].to_s
  end
end

def latest_tag

def latest_tag
  `git describe  --abbrev=0`.strip
end

def latest_tag_commit

def latest_tag_commit
  `git show-ref -s #{latest_tag}`.strip
end

def latest_tag_md5

def latest_tag_md5
  text = `git tag #{latest_tag} -n3`
  scan = text.scan(/md5=(\w{32})/)
  return scan[0][0].to_s.strip if scan.length.positive? && scan[0].length.positive?
  ""
end

def outstanding_commit?

def outstanding_commit?
  Dir.chdir(@directory) do
    return true unless `git status`.include?("nothing to commit")
  end
  false
end

def outstanding_tag?

def outstanding_tag?
  # puts `git log -n 1`

  # !latest_tag_commit.eql?(latest_commit)

  # commit 2e4cb6d6c0721e16cd06afee85b7cdc27354921b (HEAD -> master, tag: 0.0.180, origin/master, origin/HEAD)

  outstanding_commit? || !`git log -n 1`.include?("tag:")
end

def pull

def pull
  Dir.chdir(@directory) do
    run("git pull")
  end
  self
end

def push

def push
  Dir.chdir(@directory) do
    status = `git status`
    if status.include?('use "git push"')
      run("git push")
    end
  end
  self
end

def read_only?

def read_only?
  return true if !File.exists?(".git") || detached?
  return false
end

def run(command, quit_on_failure = true)

def run(command, quit_on_failure = true)
  if command.is_a?(Array)
    command.each { |subcommand| run(subcommand, quit_on_failure) }
  else
    cmd = Command.new(command).set_timeout(@timeout).run
    cmd.summary
    elapsed_str = Timer.get_elapsed_str(cmd.elapsed, 0)
    if !cmd.exitstatus.nil? && cmd.exitstatus.zero?
    else
      # display error details

      cmd.details
      if quit_on_failure
        abort
      end
    end
    cmd.save
    @commands << cmd
    cmd
  end
end

def size

def size
  Dir.chdir(@directory) do
    text = `git count-objects -v -H`
    if matches = text.match(/size: ([. \w]+)$/)
      matches[1]
    else
      text
    end
  end
end

def size_pack

def size_pack
  Dir.chdir(@directory) do
    text = `git count-objects -v -H`
    if matches = text.match(/size-pack: ([. \w]+)$/)
      matches[1]
    else
      text
    end
  end
end

def summary

def summary
  info if @verbose
  puts "[#{elapsed}] #{Rainbow(@name).yellow.bright} #{Rainbow(version).yellow.bright}"
end

def tag

def tag
  warn "[DEPRECATION] 'tag' is deprecated. Use run command(s) for better transparency."
  Dir.chdir(@directory) do
    specific_tag = `git tag -l #{@version}`.strip
    puts Rainbow("git tag - #{@version}").green if @verbose
    puts `git tag -l #{@version}` if @verbose
    if specific_tag.length.zero?
      puts "tag #{@version} not detected." if @verbose
      tag = `git describe --abbrev=0 --tags`.strip
      if @version != tag
        puts "latest tag #{@tag}" if @verbose
        run("git tag #{@version} -m'#{@version}'")
        run("git push origin #{@version}")
        # push

      end
    elsif @verbose
      puts "already has tag #{specific_tag}"
    end
  end
  self
end

def target_md5

end
@target
def target
def target_md5
  return Digest::MD5.file(target).to_s.strip if !target.nil? && File.exist?(target)
  ""
end

def to_markdown()

def to_markdown()
  md = "# #{@name}"
  md += get_markdown_nvp("Name", "Value", " ")
  md += get_markdown_nvp("-", "-", "-")
  md += get_markdown_nvp("Version", "#{@version}", " ")
  md += get_markdown_nvp("Machine", "#{Raykit::Environment::machine}", " ")
  md += get_markdown_nvp("User", "#{Raykit::Environment::user}", " ")
  @values.each do |key, value|
    md += get_markdown_nvp(key, value, " ")
  end
  @commands.each do |cmd|
    md = md + "\n" + cmd.to_markdown
  end
  md
end

def values

def values
  @values
end

def version

def version
  if @version.nil?
    # Dir.chdir(@directory) do

    #    if(Dir.glob("*.gemspec").length > 0)

    #        @version=`bump current`.gsub('Current version:','').strip

    #    else

    #        @version=Raykit::VersionHelper.detect(@name,@verbose)

    #    end

    @version = Raykit::Version.detect(@name, @verbose)
    # end

  end
  @version
end