# file      : tests/pkg-fetch.testscript
# license   : MIT; see accompanying LICENSE file

.include common.testscript auth.testscript config.testscript remote.testscript

# Source repository:
#
# pkg-fetch
# |-- hello
# |   |-- libhello-1.0.0.tar.gz
# |   `-- repositories.manifest
# `-- t1
#     |-- libfoo-1.0.0.tar.gz
#     |-- libfoo-1.1.0.tar.gz
#     `-- repositories.manifest

# Prepare repositories used by tests if running in the local mode.
#
+if! $remote
{
  rep_create += 2>!

  # Create the signed 'hello' repository.
  #
  cp -r $src/hello $out/hello
  cat <<<$cert_manifest >+$out/hello/repositories.manifest

  $rep_create --key $key $out/hello &$out/hello/packages.manifest \
                                    &$out/hello/signature.manifest

  # Create the 't1' repository.
  #
  cp -r $src/t1 $out/t1
  $rep_create $out/t1 &$out/t1/packages.manifest &$out/t1/signature.manifest
}

pkg_purge  += -d cfg
pkg_status += -d cfg
pkg_unpack += -d cfg
rep_add    += -d cfg 2>!
rep_fetch  += -d cfg --auth all 2>!
rep_list   += -d cfg --prerequisites --complements

# Let's disable the progress indication that complicates stderr output
# validation.
#
test.options += --no-progress
pkg_unpack   += --no-progress

: no-archive
:
$clone_cfg;
$* -e 2>>EOE != 0
  error: archive path argument expected
    info: run 'bpkg help pkg-fetch' for more information
  EOE

: archive-not-exist
:
$clone_cfg;
$* -e ./no-such-file 2>>/EOE != 0
  error: archive file './no-such-file' does not exist
  EOE

: no-name
:
$clone_cfg;
$* 2>>EOE != 0
  error: package name/version argument expected
    info: run 'bpkg help pkg-fetch' for more information
  EOE

: no-version
:
$clone_cfg;
$* libfoo 2>>EOE != 0
  error: package version expected
    info: run 'bpkg help pkg-fetch' for more information
  EOE

: invalid-version
:
$clone_cfg;
$* libfoo/1/2/3 2>>EOE != 0
  error: invalid package version '1/2/3' in 'libfoo/1/2/3': alpha-numeric characters expected in a component
  EOE

: no-repositories
:
$clone_cfg;
$* libfoo/1.0.0 2>>/EOE != 0
  error: configuration cfg/ has no repositories
    info: use 'bpkg rep-add' to add a repository
  EOE

: no-packages
:
{
  $clone_cfg && $rep_add $rep/t1

  $* libfoo/1.0.0 2>>/EOE != 0
    error: configuration cfg/ has no available packages
      info: use 'bpkg rep-fetch' to fetch available packages list
    EOE
}

: fetched-rep
:
{{
  +$clone_cfg && $rep_add $rep/t1 && $rep_fetch --trust-yes

  : package-not-available
  :
  $clone_cfg;
  $* libfoo/2.0.0+1 2>>/EOE != 0
    error: package libfoo 2.0.0+1 is not available
    EOE

  : package-available
  :
  {
    $clone_cfg

    $* libfoo/1.0.0 2>'fetched libfoo/1.0.0'

    $pkg_status libfoo/1.0.0 1>'libfoo fetched 1.0.0'

    $* libfoo/1.0.0 2>>/EOE != 0
      error: package libfoo already exists in configuration cfg/
        info: version: 1.0.0, state: fetched, substate: none
        info: use 'pkg-fetch --replace|-r' to replace
      EOE

    $* -e $src/t1/libfoo-1.0.0.tar.gz 2>>/EOE != 0
      error: package libfoo already exists in configuration cfg/
        info: version: 1.0.0, state: fetched, substate: none
        info: use 'pkg-fetch --replace|-r' to replace
      EOE

    $pkg_purge libfoo 2>'purged libfoo/1.0.0'
  }

  : package-replace
  :
  {
    $clone_cfg

    $* -e $src/t1/libfoo-1.0.0.tar.gz 2>'using libfoo/1.0.0 (external)'
    $pkg_status   libfoo/1.0.0        1>'libfoo fetched 1.0.0'
    $pkg_unpack   libfoo              2>'unpacked libfoo/1.0.0'

    test.arguments += --replace # Replace existing package.

    $* libfoo/1.1.0 2>'fetched libfoo/1.1.0'

    $pkg_status   libfoo/1.1.0        1>'libfoo fetched 1.1.0'
    $pkg_unpack   libfoo              2>'unpacked libfoo/1.1.0'
    $* -e $src/t1/libfoo-1.0.0.tar.gz 2>'using libfoo/1.0.0 (external)'
    $pkg_status   libfoo/1.0.0        1>'libfoo fetched 1.0.0'

    $* libfoo/1.1.0 2>'fetched libfoo/1.1.0'

    $pkg_status   libfoo/1.1.0        1>'libfoo fetched 1.1.0'
    $* -e $src/t1/libfoo-1.0.0.tar.gz 2>'using libfoo/1.0.0 (external)'
    $pkg_status   libfoo/1.0.0        1>'libfoo fetched 1.0.0'

    $*            libfoo/1.1.0  2>'fetched libfoo/1.1.0'
    $pkg_unpack   libfoo        2>'unpacked libfoo/1.1.0'
    test -d   cfg/libfoo-1.1.0
    $*            libfoo/1.1.0  2>'fetched libfoo/1.1.0'
    test -d   cfg/libfoo-1.1.0                             == 1
    $pkg_status   libfoo/1.1.0  1>'libfoo fetched 1.1.0'

    $pkg_purge libfoo 2>'purged libfoo/1.1.0'
  }

  : purge-existing
  :
  {
    $clone_cfg
    cp --no-cleanup $src/t1/libfoo-1.0.0.tar.gz ./

    $* --purge --existing libfoo-1.0.0.tar.gz 2>'using libfoo/1.0.0 (external)'

    $pkg_purge libfoo 2>'purged libfoo/1.0.0'
  }
}}

: hello
:
{
  $clone_cfg
  $rep_add $rep/hello
  $rep_fetch --trust $cert_fp &cfg/.bpkg/certs/**

  $* libhello/1.0.0 2>'fetched libhello/1.0.0'

  $pkg_status libhello/1.0.0 1>'libhello fetched 1.0.0'

  $pkg_purge libhello 2>'purged libhello/1.0.0'
}

: fetch-cache
:
{{
  # Enable the test-specific fetch caches.
  #
  options_guard = $~/.build2
  +mkdir $options_guard
  +echo '--no-default-options' >=$options_guard/bpkg.options
  +export BPKG_FETCH_CACHE=src
  rep_fetch    += --fetch-cache-path cache
  pkg_unpack   += --fetch-cache-path cache
  test.options += --fetch-cache-path cache -v

  +$cfg_create -d cfg 2>! &cfg/***

  : basics
  :
  {
    $clone_cfg && $rep_add $rep/hello

    $rep_fetch --trust $cert_fp &cache/***

    # Verify that before the package archive is cached, we download it while
    # fetching the package.
    #
    $* libhello/1.0.0 2>&1 | set out

    if $remote
      sed -n -e 's%(https://.*/libhello-1.0.0.tar.gz)%\1%p' <$out >>~%EOO%
        %.+
        EOO

    # Verify that the fetched package archive is cached.
    #
    test -f cache/pkg/packages/libhello-1.0.0.tar.gz

    rm -r cfg

    $clone_cfg && $rep_add $rep/hello

    $rep_fetch

    # Verify that now, as the package archive is cached, we don't download it
    # while fetching the package.
    #
    $* libhello/1.0.0 2>&1 | set out

    if $remote
      sed -n -e 's%(https://.*/libhello-1.0.0.tar.gz)%\1%p' <$out >:''

    # Verify that if sharing of the cached source directories is enabled, the
    # package archive doesn't appear in the configuration but only in the
    # cache.
    #
    $pkg_status libhello >'libhello fetched 1.0.0'
    test -f cfg/libhello-1.0.0.tar.gz != 0
    test -f cache/pkg/packages/libhello-1.0.0.tar.gz

    # Verify that the fetched package is unpackable.
    #
    $pkg_unpack libhello 2>'unpacked libhello/1.0.0'

    $pkg_purge libhello 2>!

    # Verify that the archive stays in the cache after the package purge.
    #
    test -f cache/pkg/packages/libhello-1.0.0.tar.gz

    # Verify that if sharing of the cached source directories is disabled, the
    # package archive appears both in the configuration and in the cache.
    #
    $* --fetch-cache no-src libhello/1.0.0 2>!

    $pkg_status libhello >'libhello fetched 1.0.0'
    test -f cfg/libhello-1.0.0.tar.gz
    test -f cache/pkg/packages/libhello-1.0.0.tar.gz

    # Verify that the fetched package is unpackable.
    #
    $pkg_unpack libhello 2>'unpacked libhello/1.0.0'

    $pkg_purge libhello 2>!
  }
}}
