require 'rake'
require 'jekyll'
require 'tmpdir'
require 'tempfile'
require 'fileutils'
require 'yaml'

# Set "rake watch" as default task
task :default => :watch

GITHUB_REPONAME = 'alt'
GITHUB_BRANCH = 'gh-pages'
GITHUB_USER = 'goatslacker'

# rake build
desc 'Build the site'
task :build do
  clean_and_copy_docs
  clean_and_copy_guide
  system 'jekyll build'
end

# rake watch
desc 'Serve and watch the site'
task :watch do
  clean_and_copy_docs
  clean_and_copy_guide
  system 'jekyll serve --watch'
end


# rake deploy
# rake deploy['commit message']
desc "Generate and deploy blog to #{GITHUB_BRANCH}"
task :deploy, [:commit_message] => [:build] do |t, args|
  commit_message = args[:commit_message] || `git log -1 --pretty=%B`
  commit_message = commit_message.gsub('"', "'")
  sha = `git log`.match(/[a-z0-9]{40}/)[0]

  Dir.mktmpdir do |tmp|
    clean_and_copy_docs
    pwd = Dir.pwd
    Dir.chdir tmp

    # setup repo in tmp dir
    system 'git init'
    system "git remote add origin git@github.com:#{GITHUB_USER}/#{GITHUB_REPONAME}.git"
    system "git pull origin #{GITHUB_BRANCH}"

    # ensure that previously generated files that are now deleted do not remain
    rm_rf Dir.glob("#{tmp}/*")
    # copy latest production site generation
    cp_r "#{pwd}/_site/.", tmp
    # prevents github from trying to parse our generated content
    system 'touch .nojekyll'

    # commit and push
    system 'git add .'
    system "git commit -m \"#{sha}: #{commit_message}\""
    system "git push origin master:refs/heads/#{GITHUB_BRANCH}"
  end
end

private

def clean_and_copy_docs
  system 'rm -rf docs/'
  system 'cp -r ../docs .'
  format_markdown_links('docs')
end

def clean_and_copy_guide
  system 'rm -rf guide/'
  system 'cp -r ../guide .'
  format_markdown_links('guide')
end

def format_markdown_links(dir)
  site = YAML.load_file('_config.yml')

  Dir[dir + '/**/*.md'].each do |file|
    temp_file = Tempfile.new('tmp')
    begin
      File.open(file, 'r') do |file|
        file.each_line do |line|
          line.scan(/(?<all>(?<name>\[.+?\])\((?<link>.+?).md(?<hash>#.+?)?\))/).each do |all, name, link, hash|
            line.gsub!(all, "#{name}(#{site['baseurl']}/#{dir}/#{link}#{hash})")
          end

          temp_file.puts line
        end
      end
      temp_file.close
      FileUtils.mv(temp_file.path, file)
    ensure
      temp_file.close
      temp_file.unlink
    end
  end
end
