# Maintainer: Trent Palmer trenttdually at gmail
# Contributor: Victor <victor@xirion.net>
# Contributor: Jan-Tarek Butt <tarek AT ring0 DOT de>
# Contributor: Erik Beran <eberan AT gmail DOT com>
# Contributor: Thor K. H. <thor at roht dot no>
# Contributor: Babken Vardanyan <483ken 4tgma1l
# Contributor: mikezackles
# Contributor: z33ky
# Contributor: stykr
# Contributor: Svenstaro
# Contributor: KaiSforza
# Contributor: Simon Gomizelj <simongmzlj@gmail.com>
# Contributor: Daniel Micay <danielmicay@gmail.com>
# Contributor: shmilee
# Contributor: foobster
# Contributor: archdria
# Contributor: Andy Weidenbaum <archbaum@gmail.com>

#=========================================================================================================#
#                                          Build Options                                                  #
#=========================================================================================================#
# _omnisharp="y" # OmniSharpServer deleted
_gocode="y"
_rust="y"
_tern="y"
_typescript="y"
_java="n"
_docs="n"
_tests="n"
_use_system_clang="ON"
_use_python2="OFF"
_use_system_python="n"  # seems broken
_use_OmniSharp_Roslyn="y"
_use_system_OmniSharp_Roslyn="y"
_use_system_jedi="n"   # seems broken

_neovim="$NEOVIM_YOUCOMPLETEME"
#=========================================================================================================#
#=========================================================================================================#



#=========================================================================================================#
#                                    Default PKGBUILD Configuration                                       #
#=========================================================================================================#
pkgname=vim-youcompleteme-git
pkgver=r2623.52632f13
pkgver() {
  cd "YouCompleteMe" || exit
  printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
pkgrel=1
pkgdesc="A code-completion engine for Vim"
arch=('any')
url='https://github.com/Valloric/YouCompleteMe'
license=('GPL3')
groups=('vim-plugins')
depends=('boost' 'boost-libs' 'nodejs' 'vim' 'clang')
makedepends=('cmake' 'git' 'make' 'curl')
install=install
source=(
'git+https://github.com/Valloric/YouCompleteMe.git' #ycm
'git+https://github.com/ycm-core/ycmd.git'          #ycm
'git+https://github.com/davidhalter/jedi.git'             #jedi
'git+https://github.com/davidhalter/parso.git'            #jedi
'git+https://github.com/davidhalter/typeshed.git'            #jedi
'git+https://github.com/numpy/numpydoc'            #jedi
'git+https://github.com/ross/requests-futures.git'  #ycm
'git+https://github.com/requests/requests.git'  #ycmd
'git+https://github.com/kjd/idna.git'  #requests
'git+https://github.com/certifi/python-certifi.git'  #requests
'git+https://github.com/chardet/chardet.git'  #requests
'git+https://github.com/urllib3/urllib3.git'  #requests
'git+https://github.com/bottlepy/bottle.git'  #ycmd
'git+https://github.com/Pylons/waitress.git'              #ycmd,jediHTTP
'git+https://github.com/ycm-core/regex.git'  #ycmd
)
sha256sums=('SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
#=========================================================================================================#
#=========================================================================================================#


#=========================================================================================================#
#                                     Applying PKBUILD Build Options                                      #
#=========================================================================================================#

if [[ "$_use_OmniSharp_Roslyn" == "y" ]];then
  if [[ "$_use_system_OmniSharp_Roslyn" == "n" ]];then
    source+=('https://github.com/OmniSharp/omnisharp-roslyn/releases/download/v1.33.0/omnisharp-mono.tar.gz')
    noextract=('omnisharp-mono.tar.gz')
    sha256sums+=('c3bd370b0e31838418756f3879269b224b1920d6f3527c8f711d661dfc008c8c')
  elif [[ "$_use_system_OmniSharp_Roslyn" == "y" ]];then
    depends+=('omnisharp-roslyn')
  fi
fi

if [[ "$_gocode" == "y" ]];then
  # ycmd
  source+=('git+https://github.com/golang/tools.git')
  sha256sums+=('SKIP')
  makedepends+=('go')
fi

if [[ "$_rust" == "y" ]];then
  # ycmd
  depends+=('rustup')
fi

if [[ "$_tern" == "y" ]]; then
  # ycmd
  makedepends+=('npm')
fi

if [[ "$_use_system_python" == "n" ]]; then
  if [[ "$_use_python2" == "OFF" ]]; then
    depends+=('python')
  elif [[ "$_use_python2" == "ON" ]]; then
    depends+=('python2')
  fi
elif [[ "$_use_system_python" == "y" ]]; then
  if [[ "$_use_python2" == "OFF" ]]; then
    depends+=('python-requests-futures' 'python-certifi' 'python-bottle' 'python-waitress' 'python-regex')
  elif [[ "$_use_python2" == "ON" ]]; then
    depends+=('python2-requests-futures' 'python2-certifi' 'python2-bottle' 'python2-waitress' 'python2-regex')
  fi
fi

if [[ "$_use_system_jedi" == "y" ]]; then
  if [[ "$_use_python2" == "OFF" ]]; then
    depends+=('python-jedi' 'python-parso' 'python-numpydoc')
  elif [[ "$_use_python2" == "ON" ]]; then
    depends+=('python2-jedi' 'python2-parso' 'python2-numpydoc')
  fi
fi
#=========================================================================================================#
#=========================================================================================================#



#=========================================================================================================#
#                                           Utility Functions                                             #
#=========================================================================================================#

gitprepare() {
  local cd_dir=$1
  local git_prefix=$2
  local c=0
  for val in "$@" ; do
    if [ $c -gt 1 ]; then
      local feed[$c]=$val
    fi
    c=$(( c + 1 ))
  done

  cd "$srcdir/$cd_dir" || exit

  git submodule init
  for gitsubvar in "${feed[@]}" ; do
    git config submodule."$git_prefix$gitsubvar".url "$srcdir/$gitsubvar"
  done

  git submodule update
  unset -v feed
}

#=========================================================================================================#
#=========================================================================================================#



#=========================================================================================================#
#                                     Standard PKGBUILD Functions                                         #
#=========================================================================================================#

prepare() {

  # Add the java completion engine dynamically...
  if [[ "$_java" == "y" ]]; then

    msg2 'Parsing out the JDTLS package version from upstream...'
    local jdtls_package_name="jdt-language-server"
    local jdtls_milestone=`egrep '^JDTLS_MILESTONE' "$srcdir/ycmd/build.py" | sed -e "s/.* = //g" -e "s/'//g"`
    local jdtls_buildstamp=`egrep '^JDTLS_BUILD_STAMP' "$srcdir/ycmd/build.py" | sed -e "s/.* = //g" -e "s/'//g"`
    if [[ "$jdtls_milestone" != "" ]] && [[ "$jdtls_buildstamp" != "" ]]; then
      msg2 'JDTLS package version matched. Downloading...'
      curl -LO http://download.eclipse.org/jdtls/milestones/"${jdtls_milestone}"/"${jdtls_package_name}"-"${jdtls_milestone}"-"${jdtls_buildstamp}".tar.gz
      tar xf "${jdtls_package_name}"-"${jdtls_milestone}"-"${jdtls_buildstamp}".tar.gz
    else
      error 'Mismatched JDTLS version'
      exit 1
    fi

  fi

  msg2 'Setting up Git submodules...'

  local YouCompleteMe=("requests-futures" "ycmd")
  local YouCompleteMeRequestsDeps=("idna" "python-certifi" "chardet" "urllib3" "requests")

  gitprepare "YouCompleteMe" "third_party/" "${YouCompleteMe[@]}"
  gitprepare "YouCompleteMe" "third_party/requests_deps/" "${YouCompleteMeRequestsDeps[@]}"

  local ycmd=("bottle" "regex" "waitress")

  gitprepare "YouCompleteMe/third_party/ycmd" "third_party/" "${ycmd[@]}"

  local ycmdJediDeps=("jedi" "parso" "numpydoc")
  gitprepare "YouCompleteMe/third_party/ycmd" "third_party/jedi_deps" "${ycmdJediDeps[@]}"

  local ycmdRequestsDeps=("python-certifi" "chardet" "idna" "requests" "urllib3")
  gitprepare "YouCompleteMe/third_party/ycmd" "third_party/requests_deps" "${ycmdRequestsDeps[@]}"

  if [[ "$_gocode" == "y" ]]; then
    gitprepare "YouCompleteMe/third_party/ycmd/third_party/go/src/golang.org/x" "" "tools"
  fi

  if [[ "$_use_OmniSharp_Roslyn" == "y" ]];then
    if [[ "$_use_system_OmniSharp_Roslyn" == "n" ]];then
      mkdir -p "$srcdir/omnisharp-roslyn"
      cd "$srcdir/omnisharp-roslyn" && tar xf ../omnisharp-mono.tar.gz .
      noextract=('omnisharp-mono.tar.gz')
    fi
  fi
}


build() {
  msg2 'Purging unneeded files...'
  rm -r "$srcdir/YouCompleteMe/python/ycm/tests"

  msg2 'Building ycmd...' # BuildYcmdLibs()
  mkdir -p "$srcdir/ycmd_build"
  cd "$srcdir/ycmd_build" || exit
  cmake -G "Unix Makefiles" -DUSE_PYTHON2=$_use_python2 -DUSE_SYSTEM_LIBCLANG="$_use_system_clang" . "$srcdir/YouCompleteMe/third_party/ycmd/cpp"
  make ycm_core

  if [[ "$_use_system_python" == "n" ]]; then
    mkdir -p "$srcdir/regex_build"
    cd "$srcdir/regex_build" || exit
    cmake -G "Unix Makefiles" -DUSE_PYTHON2=$_use_python2 -DUSE_SYSTEM_LIBCLANG="$_use_system_clang" . "$srcdir/YouCompleteMe/third_party/ycmd/third_party/cregex"
    make _regex
  fi

  if [[ "$_rust" == "y" ]]; then
    mkdir -p "$srcdir/rls_build"
    export RUSTUP_HOME="$srcdir/rls_build"
    rustup toolchain install nightly-2019-07-18
    rustup default nightly-2019-07-18
    rustup component add rls rust-analysis rust-src
  fi

  if [[ "$_gocode" == "y" ]]; then
    # export GOPATH="$GOPATH:$srcdir/YouCompleteMe/third_party/ycmd/third_party/go"
    msg2 'Building Gocode completer...' # BuildGoCode()
    cd "$srcdir/YouCompleteMe/third_party/ycmd/third_party/go/src/golang.org/x/tools/cmd/gopls" || exit
    go build
  else
    msg2 'Skipping Gocode completer...'
  fi

  if [[ "$_typescript" == "y" ]]; then
    cd "$srcdir/YouCompleteMe/third_party/ycmd" || exit
    mkdir -p "third_party/tsserver" || exit

    if [[ "$_use_python2" == "ON" ]]; then
      npm install -g --prefix third_party/tsserver typescript --python=python2
    else
      npm install -g --prefix third_party/tsserver typescript --python=python3
    fi
  else
    msg2 'Skipping typescript completer...'
  fi

  if [[ "$_tern" == "y" ]]; then
    msg2 'Building Tern completer...' # SetUpTern()
    cd "$srcdir/YouCompleteMe/third_party/ycmd/third_party/tern_runtime" || exit

    if [[ "$_use_python2" == "ON" ]]; then
      npm install --production --python=python2
    else
      npm install --production --python=python3
    fi

  else
    msg2 'Skipping Tern completer...'
  fi


  if [[ "$_java" == "y" ]]; then
    # Remove stale java completer data if any
    rm -rf "$srcdir/YouCompleteMe/third_party/ycmd/third_party/eclipse.jdt.ls/target/repository"
    mkdir -p "$srcdir/YouCompleteMe/third_party/ycmd/third_party/eclipse.jdt.ls/target/repository"
    mv "$srcdir"/{config_linux,features,plugins} "$srcdir/YouCompleteMe/third_party/ycmd/third_party/eclipse.jdt.ls/target/repository"
  fi
}


package() {

  local vimfiles_dir=usr/share/vim/vimfiles
  if [[ "$_neovim" == "y" ]]; then
    vimfiles_dir=usr/share/nvim/runtime
  fi

  mkdir -p "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party"

  cp -r "$srcdir/YouCompleteMe/third_party/ycmd/"{ycmd,ycm_core.so,CORE_VERSION} \
    "$pkgdir/$vimfiles_dir/third_party/ycmd"

  cp -r "$srcdir/YouCompleteMe/"{autoload,doc,plugin,python} \
    "$pkgdir/$vimfiles_dir"

  if [[ "$_use_OmniSharp_Roslyn" == "y" ]];then
    if [[ "$_use_system_OmniSharp_Roslyn" == "n" ]];then
      cp -r "$srcdir/omnisharp-roslyn" \
        "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party/"
    fi
  fi

  if [[ "$_rust" == "y" ]]; then
    mkdir -p "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party/rls"
    cp -r "$srcdir/rls_build/toolchains/nightly-"*"/"{bin,etc,lib,share} \
      "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party/rls"
  fi

  if [[ "$_use_system_python" == "n" ]]; then
    mkdir -p "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party/requests_deps"
    mkdir -p "$pkgdir/$vimfiles_dir/third_party/requests_deps"

    cp -r "$srcdir/YouCompleteMe/third_party/requests-futures" \
      "$pkgdir/$vimfiles_dir/third_party"
    cp -r "$srcdir/YouCompleteMe/third_party/requests_deps/"{certifi,chardet,idna,requests,urllib3} \
      "$pkgdir/$vimfiles_dir/third_party/requests_deps"

    cp -r "$srcdir/YouCompleteMe/third_party/ycmd/third_party/"{bottle,clang,cregex,waitress} \
      "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party"
    cp -r "$srcdir/YouCompleteMe/third_party/ycmd/third_party/requests_deps/"{certifi,chardet,idna,requests,urllib3} \
      "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party/requests_deps"

  elif [[ "$_use_system_python" == "y" ]]; then
    cp -r "$srcdir/YouCompleteMe/third_party/ycmd/third_party/clang" \
      "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party"
  fi
  
  if [[ "$_use_system_jedi" == "n" ]]; then
    mkdir -p "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party/jedi_deps/"{jedi,parso,numpydoc}
    cp -r "$srcdir/YouCompleteMe/third_party/ycmd/third_party/jedi_deps/jedi/jedi" \
      "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party/jedi_deps/jedi/"
    cp -r "$srcdir/YouCompleteMe/third_party/ycmd/third_party/jedi_deps/parso/parso" \
      "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party/jedi_deps/parso/"
    cp -r "$srcdir/YouCompleteMe/third_party/ycmd/third_party/jedi_deps/numpydoc/numpydoc" \
      "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party/jedi_deps/numpydoc/"
  fi

  if [[ "$_gocode" == "y" ]]; then
    mkdir -p "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party/go/src/golang.org/x/tools/cmd/gopls"
    cp "$srcdir/YouCompleteMe/third_party/ycmd/third_party/go/src/golang.org/x/tools/cmd/gopls/gopls" \
      "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party/go/src/golang.org/x/tools/cmd/gopls/gopls"
  fi

  if [[ "$_tern" == "y" ]]; then
    cp -r "$srcdir/YouCompleteMe/third_party/ycmd/third_party/tern_runtime" \
      "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party"
  fi

  if [[ "$_typescript" == "y" ]]; then
    cp -r "$srcdir/YouCompleteMe/third_party/ycmd/third_party/tsserver" \
      "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party"
  fi

  if [[ "$_java" == "y" ]]; then
    mv "$srcdir/YouCompleteMe/third_party/ycmd/third_party/eclipse.jdt.ls" "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party"
    # Force the java completion engine to create its workspace at /tmp instead which is writeable by every user
    ln -sf /tmp "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party/eclipse.jdt.ls/workspace"
  fi

  # Remove all the unnecessary git repositories
  find "$pkgdir" -name '.git*' -exec rm -fr {} +

  # Remove test files
  if [[ "$_tests" == "n" ]]; then
    find "$pkgdir" -name tests -exec rm -fr {} +
    find "$pkgdir" -name 'test' -exec rm -fr {} +
  fi

  # Remove any file we cannot compile using a specfic python version
  if [[ "$_use_python2" == "ON" ]]; then
    :
  else
    if [[ "$_use_system_python" == "n" ]]; then
      rm -r "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party/bottle/plugins/werkzeug/bottle_werkzeug.py"
      rm -r "$pkgdir/$vimfiles_dir/third_party/ycmd/third_party/bottle/plugins/sqlite/bottle_sqlite.py"
    fi  
  fi

  # Remove unneeded docs
  if [[ "$_docs" == "n" ]]; then
    find "$pkgdir" -name docs -exec rm -fr {} +
    find "$pkgdir/$vimfiles_dir/third_party/" -name doc -exec rm -fr {} +
  fi

  # Finally compile all the python files to bytecode.
  # not sure why this block causes the pkg function to fail unless you add "|| :"
  if [[ "$_use_python2" == "ON" ]]; then
    python2 -m compileall "$pkgdir" || :
  else
    python3 -m compileall "$pkgdir" || :
  fi

}

#=========================================================================================================#
#=========================================================================================================#