#! /usr/bin/env bash

# Test examples from the intro2, the Tour section. The optional <repo>
# and <trust> arguments specify the pkg repository and its fingerpring
# that contain libhello-1.0.0.
#
# Usage: intro [options] [<repo> <trust>]
#
usage="usage: $0 [options]"

owd=`pwd`
trap "{ cd $owd; exit 1; }" ERR
set -o errtrace # Trap in functions.

function error () { echo "$*" 1>&2; exit 1; }

tmp=/tmp
show=y

gcc=g++
clang=clang++-5.0
msvc=cl-15
repo=https://stage.build2.org/1/
trust="37:CE:2C:A5:1D:CF:93:81:D7:07:46:AD:66:B3:C3:90:83:B8:96:9E:34:F0:E7:B3:A2:B0:6C:EF:66:A4:BE:65"

function show () # <cmd> ...
{
  if [ $show = "y" ]; then
    echo
    echo "+ $*"
    "${@}"
  else
    "${@}"
  fi
}

cd "$tmp"

function clean ()
{
  rm -rf hello hello-gcc hello-clang hello-vc-* hello-mingw
}

## if false; then

clean

show bdep new -t exe -l c++ hello
show tree hello
show cd hello
show cat hello/hello.cxx
show cat hello/buildfile
show cat hello/testscript
show cat manifest

show bdep init -C ../hello-gcc @gcc cc config.cxx=$gcc
show bdep init -C ../hello-clang @clang cc config.cxx=$clang
show ls -d -1 ../hello*

show bdep init -C ../hello-vc-debug @debug cc config.cxx=$msvc \
  "config.cc.coptions=/MDd /Z7" config.cc.loptions=/DEBUG
show bdep init -C ../hello-vc-release @release cc config.cxx=$msvc \
   config.cc.coptions=/O2

show bdep status
show b
show b test
show hello/hello World

show tree ../hello-gcc

show bdep status @clang
show b ../hello-clang/hello/
show b test: ../hello-clang/hello/
show ../hello-clang/hello/hello/hello World

b clean: ../hello-clang/hello/
show bdep test @clang
show bdep test @gcc @clang

show bdep init -C ../hello-mingw @mingw cc config.cxx=x86_64-w64-mingw32-g++
show bdep update @mingw
show bdep test @mingw
show ../hello-mingw/hello/hello/hello.exe Windows

show git add .
show git commit -m "Initial implementation"
show git remote add origin git@github.com:boris-kolpackov/hello.git
show git push origin master -u --force
show bdep ci --simulate success

show bdep deinit @gcc @clang

cd ..
##fi

##if false; then

clean
show bdep new -C hello-gcc @gcc -t exe -l c++ hello cc config.cxx=$gcc
cd hello
show bdep init -C ../hello-clang @clang cc config.cxx=$clang

# Package Repositories
#
show bpkg rep-info https://git.build2.org/hello/libhello.git
show bpkg rep-info https://git.build2.org/hello/libhello.git#HEAD

# Adding and Removing Dependencies
#
cat <<EOF >>repositories.manifest
:
role: prerequisite
location: $repo
EOF
cat <<EOF >>manifest
depends: libhello ^1.0.0
EOF
sed -i -re 's/^#import/import/' hello/buildfile
cat <<EOF >hello/hello.cxx
#include <iostream>

#include <libhello/hello.hxx>

using namespace std;

int main (int argc, char* argv[])
{
  if (argc < 2)
  {
    cerr << "error: missing name" << endl;
    return 1;
  }

  hello::say_hello (cout, "World");
}
EOF

show bdep status

cat <<EOF >>repositories.manifest
trust: $trust
EOF

show bdep sync

echo '' >>manifest
show b

show bdep status -ai
show bdep sync -a

show bdep test -ai

sed -i -re 's/^import/#import/' hello/buildfile
sed -i -re 's/^depends: libhello/#depends: libhello/' manifest

show bdep status
show bdep sync

# Upgrading and Downgrading Dependencies
#
sed -i -re 's/^#import/import/' hello/buildfile
sed -i -re 's/^#depends: libhello/depends: libhello/' manifest
bdep sync

cat <<EOF >>repositories.manifest
:
role: prerequisite
location: https://git.build2.org/hello/libhello.git
EOF

show bdep fetch
show bdep status libhello
show bdep sync libhello

show bdep status -r

show bdep status -o libhello
show bdep sync libhello/1.0.0

# Using Unpackaged Dependencies.
#
cd ..
rm -rf libextra libextra-gcc unpkg-gcc hello-gcc-1
show bdep new -C libextra-gcc -t lib -l c++ libextra cc config.cxx=$gcc
show b install: libextra/ config.install.root=/tmp/unpkg-gcc
show tree unpkg-gcc
cd hello

show bdep init -C ../hello-gcc-1 @gcc1 cc config.cxx=$gcc \
config.cc.poptions=-I$tmp/unpkg-gcc/include \
config.cc.loptions=-L$tmp/unpkg-gcc/lib

sed -i -re 's/^libs =/import libs = libextra%lib{extra}/' hello/buildfile
cat <<EOF >>hello/hello.cxx
#include <libextra/extra.hxx>

void f ()
{
  extra::say_hello (cout, "Extra");
}
EOF

show b test: ../hello-gcc-1/

show b configure: ../hello-gcc/ \
config.cc.poptions+=-I$tmp/unpkg-gcc/include \
config.cc.loptions+=-L$tmp/unpkg-gcc/lib
show b test

# Using System-Installed Dependencies.
#
cat <<EOF >>manifest
depends: libsqlite3 ^3.18.0
EOF
sed -i -re 's/^import libs =/import libs = libsqlite3%lib{sqlite3}/' hello/buildfile
cat <<EOF >>hello/hello.cxx
#include <sqlite3.h>
EOF

show bdep sync ?sys:libsqlite3

cd ..

# Versioning and Release Management.
#
clean
show bdep new -C hello-gcc @gcc -t exe -l c++ hello cc config.cxx=$gcc
cd hello

git remote add origin git@github.com:boris-kolpackov/hello.git
git push origin :build2-control  || true
git push -d origin v0.1.0-a.1    || true
git push -d origin v0.1.0        || true

git add .
git commit -m "Initial implementation"
git push -f -u

show bdep status
show b info
show bdep sync
show bdep status

echo '' >>buildfile
git commit -a -m "Another commit"

show bdep status

show bdep release --alpha --push
show bdep release --no-open --push

show bdep publish --simulate success

show bdep release --open --push

cd ..
## fi

# Developing Multiple Packages and Projects (multi-project).
#
rm -rf libhello

clean
show bdep new -C hello-gcc @gcc -t exe -l c++ hello cc config.cxx=$gcc
cd hello
show bdep init -C ../hello-clang @clang cc config.cxx=$clang
cd ..

show bdep new -t lib -l c++ libhello
show cd libhello

show bdep init -A ../hello-gcc @gcc
show bdep init -A ../hello-clang @clang

show cd ../hello
cat <<EOF >>manifest
depends: libhello
EOF
sed -i -re 's/^#import/import/' hello/buildfile

show bdep test -i
cd ..

# Developing Multiple Packages and Projects (multi-package).
#
clean
show bdep new -C hello-gcc @gcc -t exe -l c++ hello cc config.cxx=$gcc
show cd hello
show bdep init -C ../hello-clang @clang cc config.cxx=$clang

mkdir tmp
mv build hello buildfile manifest .gitignore tmp/
mv tmp hello

show bdep new --package -t lib -l c++ libhello
show cat packages.manifest
cat <<EOF >>packages.manifest
:
location: hello/
EOF

show cd libhello
show bdep init -a

show cd ..
cat <<EOF >>hello/manifest
depends: libhello
EOF
sed -i -re 's/^#import/import/' hello/hello/buildfile

show bdep test
cd ..

# Package Consumption.
#
rm -rf tools

show bpkg create -d tools cc     \
  config.cxx=$gcc                \
  config.cc.coptions=-O3         \
  config.install.root=/opt/tools \
  config.install.sudo=sudo       \
  config.bin.rpath=/opt/tools/lib

show cd tools

show bpkg build hello@https://git.build2.org/hello/hello.git
show bpkg install hello
show /opt/tools/bin/hello World
show tree /opt/tools
show bpkg uninstall hello
show bpkg drop hello

echo "finished"