# file      : tests/cfg-link.testscript
# license   : MIT; see accompanying LICENSE file

.include common.testscript remote.testscript

# Source repository (see pkg-build for details):
#
# cfg-unlink
# `-- t7a

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

  cp -r $src/t7a $out/t7a && $rep_create $out/t7a &$out/t7a/packages.manifest
end

cfg_create +=             2>!
cfg_info   += --link
pkg_build  += --yes       2>!
pkg_drop   += --yes       2>!
rep_add    +=             2>!
rep_fetch  += --trust-yes 2>!

cfg1_uuid = '18f48b4b-b5d9-4712-b98c-1930df1c4228'
cfg2_uuid  ='28f48b4b-b5d9-4712-b98c-1930df1c4228'

+$cfg_create -d cfg1 --name 'main'   --uuid "$cfg1_uuid"             &cfg1/***
+$cfg_create -d cfg2 --name 'shared' --uuid "$cfg2_uuid" --type host &cfg2/***

+$cfg_link -d cfg1 cfg2 2>!

clone_root_cfgs = cp -r $~/cfg1 $~/cfg2 ./

: unlink
:
{
  : name-dir
  :
  {
    $clone_root_cfgs;

    $* -d cfg1 cfg2 --name 'host' 2>/'error: both --name and directory argument specified' != 0
  }

  : dir
  :
  {
    $clone_root_cfgs;

    $* -d cfg1 cfg1 2>/"error: no configuration with path $~/cfg1/ is linked with cfg1/" != 0;

    $* -d cfg1 cfg2 2>/"unlinked configuration $~/cfg2/";

    $cfg_info -d cfg1 >>/"EOO";
      path: $~/cfg1/
      uuid: $cfg1_uuid
      type: target
      name: main
      EOO

    $cfg_info -d cfg2 >>/"EOO"
      path: $~/cfg2/
      uuid: $cfg2_uuid
      type: host
      name: shared
      EOO
  }

  : name
  :
  {
    $clone_root_cfgs;

    $* -d cfg1 --name 'target' 2>/"error: no configuration with name 'target' is linked with cfg1/" != 0;

    $* -d cfg1 --name 'shared' 2>/"unlinked configuration $~/cfg2/";

    $cfg_info -d cfg1 >>/"EOO";
      path: $~/cfg1/
      uuid: $cfg1_uuid
      type: target
      name: main
      EOO

    $cfg_info -d cfg2 >>/"EOO"
      path: $~/cfg2/
      uuid: $cfg2_uuid
      type: host
      name: shared
      EOO
  }

  : id
  :
  {
    $clone_root_cfgs;

    $* -d cfg1 --id 2 2>/"error: no configuration with id 2 is linked with cfg1/" != 0;

    $* -d cfg1 --id 1 2>/"unlinked configuration $~/cfg2/";

    $cfg_info -d cfg1 >>/"EOO";
      path: $~/cfg1/
      uuid: $cfg1_uuid
      type: target
      name: main
      EOO

    $cfg_info -d cfg2 >>/"EOO"
      path: $~/cfg2/
      uuid: $cfg2_uuid
      type: host
      name: shared
      EOO
  }

  : uuid
  :
  {
    $clone_root_cfgs;

    $* -d cfg1 --uuid $cfg1_uuid 2>/"error: no configuration with uuid $cfg1_uuid is linked with cfg1/" != 0;

    $* -d cfg1 --uuid $cfg2_uuid 2>/"unlinked configuration $~/cfg2/";

    $cfg_info -d cfg1 >>/"EOO";
      path: $~/cfg1/
      uuid: $cfg1_uuid
      type: target
      name: main
      EOO

    $cfg_info -d cfg2 >>/"EOO"
      path: $~/cfg2/
      uuid: $cfg2_uuid
      type: host
      name: shared
      EOO
  }

  : mutual
  :
  {
    $clone_root_cfgs;

    $cfg_link -d cfg2 cfg1 2>!;

    $* -d cfg1 cfg2 2>>/"EOE";
      info: configurations cfg2/ and cfg1/ are mutually linked, turning the link to cfg2/ into implicit backlink
      unlinked configuration $~/cfg2/
      EOE

    $cfg_info -d cfg1 >>/"EOO";
      path: $~/cfg1/
      uuid: $cfg1_uuid
      type: target
      name: main
      EOO

    $cfg_info -d cfg2 >>/"EOO"
      path: $~/cfg2/
      uuid: $cfg2_uuid
      type: host
      name: shared

      path: $~/cfg1/
      uuid: $cfg1_uuid
      type: target
      name: main
      EOO
  }

  : dependency
  :
  {
    $clone_root_cfgs;

    $rep_add -d cfg1 $rep/t7a && $rep_fetch -d cfg1;

    $pkg_build -d cfg1 libbar &cfg2/.bpkg/build2/***;

    $* -d cfg1 cfg2 2>>/EOE != 0;
      error: configuration cfg1/ still depends on configuration cfg2/
        info: package foo [cfg2/] has dependents:
        info: package libbar on foo ^1.0.0
      EOE

    $pkg_drop -d cfg1 --keep-unused libbar;

    $* -d cfg1 cfg2 2>>/"EOE";
      unlinked configuration $~/cfg2/
      EOE

    $cfg_info -d cfg1 >>/"EOO";
      path: $~/cfg1/
      uuid: $cfg1_uuid
      type: target
      name: main
      EOO

    $cfg_info -d cfg2 >>/~"%EOO%";
      path: $~/cfg2/
      uuid: $cfg2_uuid
      type: host
      name: shared

      path: $~/cfg2/.bpkg/build2/
      %uuid: .{36}%
      type: build2
      name: build2
      EOO

    $pkg_drop -d cfg1 libbaz;
    $pkg_drop -d cfg2 foo
  }

  : dependency-private
  :
  {
    $clone_root_cfgs;

    $rep_add -d cfg2 $rep/t7a && $rep_fetch -d cfg2;

    $pkg_build -d cfg2 foo;

    $* -d cfg2 --name build2 2>>/EOE != 0;
      error: configuration cfg2/ still depends on private configuration cfg2/.bpkg/build2/
        info: package libbuild2-bar [cfg2/.bpkg/build2/] has dependents:
        info: package foo on libbuild2-bar ^1.0.0
      EOE

    $pkg_drop -d cfg2 --keep-unused foo;

    test -d cfg2/.bpkg/build2/;

    $* -d cfg2 --name build2 2>>/"EOE";
      unlinked and removed configuration $~/cfg2/.bpkg/build2/
      EOE

    $cfg_info -d cfg2 >>/"EOO";
      path: $~/cfg2/
      uuid: $cfg2_uuid
      type: host
      name: shared
      EOO

    test -d cfg2/.bpkg/build2/ == 1;

    $pkg_drop -d cfg2 libbaz
  }
}
: remove-dangling
:
{
  : success
  :
  {
    $clone_root_cfgs;

    mv cfg1 cfg3;

    $* -d cfg2 --dangling 2>'removed 1 dangling implicit backlink(s)';
    $* -d cfg2 --dangling 2>'removed 0 dangling implicit backlink(s)'
  }

  : error
  :
  {
    $clone_root_cfgs;

    $* -d cfg1 --dangling --name 'host' 2>'error: both --dangling and --name specified' != 0
  }
}
