#!/bin/bash

# Opens the BitBucket/GitHub page for a repo/branch in your browser.
#
# git open
# git open [remote] [branch]


# are we in a git repo?
git rev-parse --is-inside-work-tree &>/dev/null

if [[ $? != 0 ]]; then
  echo "Not a git repository." 1>&2
  exit 1
fi


# assume origin if not provided
# fallback to upstream if neither is present.
remote="origin"
if [ -n "$1" ]; then
  if [ "$1" == "issue" ]; then
    currentBranch=$(git symbolic-ref -q --short HEAD)
    regex='^issue'
    if [[ $currentBranch =~ $regex ]]; then
      issue=${currentBranch#*#}
    else
      echo "'git open issue' expect branch naming to be issues/#123" 1>&2
      exit 1
    fi
  else
    remote="$1"
  fi
fi

remote_url="remote.${remote}.url"

giturl=$(git config --get "$remote_url")
if [ -z "$giturl" ]; then
  echo "$remote_url not set." 1>&2
  exit 1
fi

# get current branch
if [ -z "$2" ]; then
  branch=$(git symbolic-ref -q --short HEAD)
else
  branch="$2"
fi

# Make # and % characters url friendly
#   github.com/paulirish/git-open/pull/24
branch=${branch//%/%25} && branch=${branch//#/%23}

# URL normalization
# GitHub gists
if grep -q gist.github <<<$giturl; then
  giturl=${giturl/git\@gist.github\.com\:/https://gist.github.com/}
  providerUrlDifference=tree

# GitHub
elif grep -q github <<<$giturl; then
  giturl=${giturl/git\@github\.com\:/https://github.com/}

  # handle SSH protocol (links like ssh://git@github.com/user/repo)
  giturl=${giturl/#ssh\:\/\/git\@github\.com\//https://github.com/}

  providerUrlDifference=tree

# Bitbucket
elif grep -q bitbucket <<<$giturl; then
  giturl=${giturl/git\@bitbucket\.org\:/https://bitbucket.org/}
  # handle SSH protocol (change ssh://https://bitbucket.org/user/repo to https://bitbucket.org/user/repo)
  giturl=${giturl/#ssh\:\/\/git\@/https://}

  rev="$(git rev-parse HEAD)"
  git_pwd="$(git rev-parse --show-prefix)"
  providerUrlDifference="src/${rev}/${git_pwd}"
  branch="?at=${branch}"

# Atlassian Bitbucket Server
elif grep -q "/scm/" <<<$giturl; then
  re='(.*)/scm/(.*)/(.*)\.git'
  if [[ $giturl =~ $re ]]; then
    giturl=${BASH_REMATCH[1]}/projects/${BASH_REMATCH[2]}/repos/${BASH_REMATCH[3]}
    providerUrlDifference=browse
    branch="?at=refs%2Fheads%2F${branch}"
  fi

# GitLab
else
  # custom GitLab
  gitlab_domain=$(git config --get gitopen.gitlab.domain)
  gitlab_ssh_domain=$(git config --get gitopen.gitlab.ssh.domain)
  gitlab_ssh_domain=${gitlab_ssh_domain:-$gitlab_domain}
  gitlab_ssh_port=$(git config --get gitopen.gitlab.ssh.port)
  
  gitlab_protocol=$(git config --get gitopen.gitlab.protocol)
  if [ -z "$gitlab_protocol" ]; then
      gitlab_protocol=https
  fi

if [ -n "$gitlab_domain" ]; then
    if egrep -q "${gitlab_domain}|${gitlab_ssh_domain}" <<<$giturl; then

      # Handle GitLab's default SSH notation (like git@gitlab.domain.com:user/repo)
      giturl=${giturl/git\@${gitlab_ssh_domain}\:/${gitlab_protocol}://${gitlab_domain}/}

      # handle SSH protocol (links like ssh://git@gitlab.domain.com/user/repo)
      giturl=${giturl/#ssh\:\/\//${gitlab_protocol}://}

      # remove git@ from the domain
      giturl=${giturl/git\@${gitlab_ssh_domain}/${gitlab_domain}/}

      # remove SSH port
      if [ -n "$gitlab_ssh_port" ]; then
        giturl=${giturl/\/:${gitlab_ssh_port}\///}
      fi
      providerUrlDifference=tree
    fi
    # hosted GitLab
  elif grep -q gitlab <<<$giturl; then
    giturl=${giturl/git\@gitlab\.com\:/https://gitlab.com/}
    providerUrlDifference=tree
  fi
fi
giturl=${giturl%\.git}

if [ -n "$issue" ]; then
  giturl="${giturl}/issues/${issue}"
elif [ -n "$branch" ]; then
  giturl="${giturl}/${providerUrlDifference}/${branch}"
fi

# simplify URL for master
giturl=${giturl/tree\/master/}

# get current open browser command
case $( uname -s ) in
  Darwin)  open=open;;
  MINGW*)  open=start;;
  CYGWIN*) open=cygstart;;
  MSYS*)   open="powershell.exe –NoProfile Start";;
  *)       open=${BROWSER:-xdg-open};;
esac

# open it in a browser
$open "$giturl" &> /dev/null
exit $?
