#!/usr/bin/env ruby

require "optparse"

ROOT = File.expand_path("../../", __FILE__)


# Break a repository URL into its separate components
def parse_url(input)
  hosts = "github\.com|bitbucket\.org|gitlab\.com"

  # HTTPS/HTTP link pointing to recognised hosts
  if input =~ /^(?:https?:\/\/)?(?:[^.@]+@)?(?:www\.)?(#{hosts})\/([^\/]+)\/([^\/]+)/i
    { host: $1.downcase(), user: $2, repo: $3.sub(/\.git$/, "") }
  # SSH
  elsif input =~ /^git@(#{hosts}):([^\/]+)\/([^\/]+)\.git$/i
    { host: $1.downcase(), user: $2, repo: $3 }
  # provider:user/repo
  elsif input =~ /^(github|bitbucket|gitlab):\/?([^\/]+)\/([^\/]+)\/?$/i
    { host: $1.downcase(), user: $2, repo: $3 }
  # user/repo - Common GitHub shorthand
  elsif input =~ /^\/?([^\/]+)\/([^\/]+)\/?$/
    { host: "github.com", user: $1, repo: $2 }
  else
    raise "Unsupported URL: #{input}"
  end
end

# Isolate the vendor-name component of a submodule path
def parse_submodule(name)
  name =~ /^(?:.*(?:vendor\/)?grammars\/)?([^\/]+)/i
  path = "vendor/grammars/#{$1}"
  unless File.exist?("#{ROOT}/" + path)
    warn "Submodule '#{path}' does not exist. Aborting."
    exit 1
  end
  path
end

# Print debugging feedback to STDOUT if running with --verbose
def log(msg)
  puts msg if $verbose
end


usage = """Usage:
  #{$0} [-v|--verbose] [--replace grammar] url
Examples:
  #{$0} https://github.com/Alhadis/language-roff
  #{$0} --replace sublime-apl https://github.com/Alhadis/language-apl
"""

$replace = nil
$verbose = false

OptionParser.new do |opts|
  opts.banner = usage
  opts.on("-v", "--verbose", "Print verbose feedback to STDOUT") do
    $verbose = true
  end
  opts.on("-rSUBMODULE", "--replace=SUBMODDULE", "Replace an existing grammar submodule.") do |name|
    $replace = name
  end
end.parse!


$url = ARGV[0]

# No URL? Print a usage message and bail.
unless $url
  warn usage
  exit 1;
end

# Ensure the given URL is an HTTPS link
parts    = parse_url $url
https    = "https://#{parts[:host]}/#{parts[:user]}/#{parts[:repo]}"
repo_new = "vendor/grammars/#{parts[:repo]}"
repo_old = parse_submodule($replace) if $replace

Dir.chdir(ROOT)

if repo_old
  log "Deregistering: #{repo_old}"
  `git submodule deinit #{repo_old}`
  `git rm -rf #{repo_old}`
  `script/convert-grammars`
end

log "Registering new submodule: #{repo_new}"
`git submodule add -f #{https} #{repo_new}`
exit 1 if $?.exitstatus > 0
`script/convert-grammars --add #{repo_new}`

log "Confirming license"
if repo_old
  `script/licensed`
else
  `script/licensed --module "#{repo_new}"`
end

log "Updating grammar documentation in vendor/REAEDME.md"
`bundle exec rake samples`
`script/list-grammars`
