#!/usr/bin/env bash-shlib
# -*- mode: shell-script -*-

include shunit

depends sed grep git mkdir readlink

export -f matches
export grep

tmp=/tmp
tprog="../bin/compose-core"
tprog=$(readlink -f $tprog)


export PATH=".:$PATH"
short_tprog=$(basename "$tprog")


##
## Convenience function
##

init_test() {
    test_tmpdir=$(mktemp -d -t tmp.XXXXXXXXXX)
    cd "$test_tmpdir"
    export CACHEDIR="$test_tmpdir/.cache"
    export VARDIR="$test_tmpdir/.var"
    mkdir -p "$CACHEDIR"
}



tear_test() {
    rm -rf "$test_tmpdir"
}


##
## Tests
##


function test_all_relations_simple {

    init_test

    export DISABLE_SYSTEM_CONFIG_FILE=true

    assert_list <<EOF

### Testing simple case

## -- simple case with only one service with one relation, no uses/provides

export CHARM_STORE=$test_tmpdir
mkdir -p $test_tmpdir/{www,mysql}
cat <<EOF2 > $test_tmpdir/www/metadata.yml
EOF2

touch $test_tmpdir/mysql/metadata.yml

cat <<EOF2 > $test_tmpdir/compose.yml
www:
  charm: www
  relations:
    mysql-db:
      mysql:
        label: value
EOF2

. "$tprog"

_setup_state_dir
COMPOSE_YML_FILE=$test_tmpdir/compose.yml

out=\$(set -o pipefail
  get_all_relations www mysql | tr '\0' '\n') || exit 3
expected="www
mysql-db
mysql
label: value

True"

[[ "\$out" == "\$expected" ]] || {
    echo "doesn't end with: \$expected" >&2
    echo "\$out"
    exit 1
}


## -- simple case, 1 uses, already present

export CHARM_STORE=$test_tmpdir
mkdir -p $test_tmpdir/{www,mysql}
cat <<EOF2 > $test_tmpdir/www/metadata.yml
uses:
  mysql-db:
    constraint: optional
    default-options:
       label: from-default-options
       label2: from-default-options
EOF2

touch $test_tmpdir/mysql/metadata.yml

cat <<EOF2 > $test_tmpdir/compose.yml
www:
  charm: www
  relations:
    mysql-db:
      mysql:
        label: value
EOF2

. "$tprog"

_setup_state_dir
COMPOSE_YML_FILE=$test_tmpdir/compose.yml

out=\$(set -o pipefail
  get_all_relations www mysql | tr '\0' '\n') || exit 3
expected="www
mysql-db
mysql
label: value
label2: from-default-options
True"

[[ "\$out" == "\$expected" ]] || {
    echo "doesn't end with: \$expected" >&2
    echo --- OUT: >&2
    echo "\$out" >&2
    exit 1
}


## -- simple case, 1 uses, optional, not present

export CHARM_STORE=$test_tmpdir
mkdir -p $test_tmpdir/{www,mysql}
cat <<EOF2 > $test_tmpdir/www/metadata.yml
uses:
  mysql-db:
    constraint: optional
    default-options:
       label: from-default-options
       label2: from-default-options
EOF2

touch $test_tmpdir/mysql/metadata.yml

cat <<EOF2 > $test_tmpdir/compose.yml
www:
  charm: www
EOF2

. "$tprog"

_setup_state_dir
COMPOSE_YML_FILE=$test_tmpdir/compose.yml


out=\$(set -o pipefail
  get_all_relations www mysql 2>&1 >/dev/null) || exit 3
expected=""

[[ "\$out" == "\$expected" ]] || {
    echo "doesn't end with: \$expected" >&2
    echo "\$out"
    exit 1
}



out=\$(set -o pipefail
  get_all_relations www mysql | tr '\0' '\n') || exit 3
expected=""

[[ "\$out" == "\$expected" ]] || {
    echo "doesn't end with: \$expected" >&2
    echo "\$out"
    exit 1
}


## -- simple case, 1 uses, optional with solves, not present

export CHARM_STORE=$test_tmpdir
mkdir -p $test_tmpdir/{www,mysql}
cat <<EOF2 > $test_tmpdir/www/metadata.yml
uses:
  mysql-db:
    constraint: optional
    solves:
       missing-feature: foo
    default-options:
       label: from-default-options
       label2: from-default-options
EOF2

touch $test_tmpdir/mysql/metadata.yml

cat <<EOF2 > $test_tmpdir/compose.yml
www:
  charm: www
EOF2

. "$tprog"

_setup_state_dir
COMPOSE_YML_FILE=$test_tmpdir/compose.yml


out=\$(set -o pipefail
  get_all_relations www mysql 2>&1 >/dev/null) || exit 3
expected="Notice"

[[ "\$out" == *"\$expected"* ]] || {
    echo "doesn't contain: \$expected" >&2
    echo "\$out"
    exit 1
}




## -- simple case, 1 uses, auto-pair, present

export CHARM_STORE=$test_tmpdir
mkdir -p $test_tmpdir/{www,mysql}
cat <<EOF2 > $test_tmpdir/www/metadata.yml
uses:
  mysql-db:
    constraint: optional
    auto: pair
    default-options:
       label: from-default-options
       label2: from-default-options
EOF2

touch $test_tmpdir/mysql/metadata.yml

cat <<EOF2 > $test_tmpdir/compose.yml
www:
  charm: www
  relations:
    mysql-db:
      mysql:
        label: value
EOF2

. "$tprog"

_setup_state_dir
COMPOSE_YML_FILE=$test_tmpdir/compose.yml

out=\$(set -o pipefail
  get_all_relations www mysql | tr '\0' '\n') || exit 3
expected="www
mysql-db
mysql
label: value
label2: from-default-options
True"

[[ "\$out" == "\$expected" ]] || {
    echo "doesn't end with: \$expected" >&2
    echo "\$out"
    exit 1
}



## -- simple case, 1 uses, auto-pair, not present, no provider

export CHARM_STORE=$test_tmpdir
mkdir -p $test_tmpdir/{www,mysql}
cat <<EOF2 > $test_tmpdir/www/metadata.yml
uses:
  mysql-db:
    constraint: optional
    auto: pair
    default-options:
       label: from-default-options
       label2: from-default-options
EOF2

touch $test_tmpdir/mysql/metadata.yml

cat <<EOF2 > $test_tmpdir/compose.yml
www:
  charm: www
EOF2

. "$tprog"

_setup_state_dir
COMPOSE_YML_FILE=$test_tmpdir/compose.yml

out=\$(set -o pipefail
  get_all_relations www mysql | tr '\0' '\n') || exit 3
expected=""

[[ "\$out" == "\$expected" ]] || {
    echo "doesn't end with: \$expected" >&2
    echo "\$out"
    exit 1
}


## -- simple case, 1 uses, auto-pair, not present, 1 provider

export CHARM_STORE=$test_tmpdir
mkdir -p $test_tmpdir/{www,mysql}
cat <<EOF2 > $test_tmpdir/www/metadata.yml
uses:
  mysql-db:
    constraint: optional
    auto: pair
    default-options:
       label: from-default-options
       label2: from-default-options
EOF2

cat <<EOF2 > $test_tmpdir/mysql/metadata.yml
provides:
  mysql-db:
EOF2

cat <<EOF2 > $test_tmpdir/compose.yml
www:
  charm: www
EOF2

. "$tprog"

_setup_state_dir
COMPOSE_YML_FILE=$test_tmpdir/compose.yml

out=\$(set -o pipefail
  get_all_relations www mysql | tr '\0' '\n') || exit 3
expected="www
mysql-db
mysql
label: from-default-options
label2: from-default-options
True"

[[ "\$out" == "\$expected" ]] || {
    echo "--- EXPECTED" >&2
    echo "\$expected" >&2
    echo "--- OUT" >&2
    echo "\$out" >&2

    exit 1
}


## -- simple case, 1 uses, auto-pair, not present, 2 providers

export CHARM_STORE=$test_tmpdir
mkdir -p $test_tmpdir/{www,mysql,mysql2}
cat <<EOF2 > $test_tmpdir/www/metadata.yml
uses:
  mysql-db:
    constraint: optional
    auto: pair
    default-options:
       label: from-default-options
       label2: from-default-options
EOF2

cat <<EOF2 > $test_tmpdir/mysql/metadata.yml
provides:
  mysql-db:
EOF2

cat <<EOF2 > $test_tmpdir/mysql2/metadata.yml
provides:
  mysql-db:
EOF2

cat <<EOF2 > $test_tmpdir/compose.yml
www:
  charm: www
EOF2

. "$tprog"

_setup_state_dir
COMPOSE_YML_FILE=$test_tmpdir/compose.yml

out=\$(set -o pipefail
  get_all_relations www mysql mysql2 2>&1 >/dev/null) || exit 3

expected="> 1"

[[ "\$out" == *"\$expected"* ]] || {
    echo "doesn't contain: \$expected" >&2
    echo "\$out"
    exit 1
}

# Remember, it is cached
out=\$(set -o pipefail
  get_all_relations www mysql mysql2 | tr '\0' '\n') || exit 3
expected=""

[[ "\$out" == "\$expected" ]] || {
    echo "doesn't end with: \$expected" >&2
    echo "\$out"
    exit 1
}


EOF

    tear_test
}



function test_all_relations_missing {

    init_test

    export DISABLE_SYSTEM_CONFIG_FILE=true

    assert_list <<EOF

### Testing missing services at first call

## -- 1 service, connection to another, no use/provide

export CHARM_STORE=$test_tmpdir
mkdir -p $test_tmpdir/{www,mysql}
cat <<EOF2 > $test_tmpdir/www/metadata.yml
EOF2

cat <<EOF2 > $test_tmpdir/mysql/metadata.yml
EOF2

cat <<EOF2 > $test_tmpdir/compose.yml
www:
  relations:
    mysql-db: mysql
EOF2

. "$tprog"

_setup_state_dir
COMPOSE_YML_FILE=$test_tmpdir/compose.yml

out=\$(set -o pipefail
  get_all_relations www | tr '\0' '\n') || exit 3
expected="www
mysql-db
mysql

True"

[[ "\$out" == "\$expected" ]] || {
    echo "doesn't end with: \$expected" >&2
    echo "OUT:" >&2
    echo "\$out" >&2
    exit 1
}


## -- 1 service, connection to another that auto-pair with first

export CHARM_STORE=$test_tmpdir
mkdir -p $test_tmpdir/{www,mysql}
cat <<EOF2 > $test_tmpdir/www/metadata.yml
provides:
  www-proxy:
EOF2

cat <<EOF2 > $test_tmpdir/mysql/metadata.yml
uses:
  www-proxy:
    constraint: optional
    auto: pair
EOF2

cat <<EOF2 > $test_tmpdir/compose.yml
www:
  relations:
    mysql-db: mysql
EOF2

. "$tprog"

_setup_state_dir
COMPOSE_YML_FILE=$test_tmpdir/compose.yml

out=\$(set -o pipefail
  get_all_relations www | tr '\0' '\n') || exit 3
expected="\
www
mysql-db
mysql

True
mysql
www-proxy
www

True"

[[ "\$out" == "\$expected" ]] || {
    echo "DIFF:" >&2
    diff -u <(echo "\$expected") <(echo "\$out") >&2
    exit 1
}





EOF

    tear_test
}






continue_on_error="0" testbench $*