[buildout]
extends =
   ../../component/caddy/buildout.cfg
   ../../component/git/buildout.cfg
   ../../component/bash/buildout.cfg
   ../../component/bash-completion/buildout.cfg
   ../../component/fish-shell/buildout.cfg
   ../../component/tmux/buildout.cfg
   ../../component/tig/buildout.cfg
   ../../component/vim/buildout.cfg
   ../../component/curl/buildout.cfg
   ../../component/coreutils/buildout.cfg
   ../../component/java-jdk/buildout.cfg
   ../../component/fonts/buildout.cfg
   ../../stack/nodejs.cfg
   ../../stack/slapos.cfg
   ../../stack/monitor/buildout.cfg
   ../../component/defaults.cfg
   ./download-plugins.cfg
   ./buildout.hash.cfg

parts =
  theia-wrapper
  slapos-cookbook
  instance-theia
  instance

# default for slapos-standalone
shared-part-list =

# We keep the gcc part in sync with the one from erp5 software, so that when we install
# erp5 inside theia's slapos parts can be shared.
[gcc]
max_version = 0


[nodejs]
<= nodejs-12.18.3

[yarn]
<= yarn-1.17.3

[slapos-standalone]
recipe = zc.recipe.egg
eggs =
  slapos.core
scripts = ${:_buildout_section_name_}
script-path = ${buildout:bin-directory}/${:scripts}
# XXX generate a fake entry point for a non existant module, that will not
# be used because we exit in initialization step
entry-points =
  ${:scripts}=not_used:main
initialization =
  import argparse
  import glob
  import os.path
  import sys
  import signal
  import time

  import slapos.slap.standalone

  parser = argparse.ArgumentParser()
  parser.add_argument('base_directory')
  parser.add_argument('ipv4')
  parser.add_argument('ipv6')
  parser.add_argument('server_port', type=int)
  parser.add_argument('computer_id')
  parser.add_argument('--sr')
  parser.add_argument('--srtype')
  forwarded_arguments = parser.add_argument_group('forwarded')
  forwarded_arguments.add_argument('master_url')
  forwarded_arguments.add_argument('computer')
  forwarded_arguments.add_argument('partition')
  # cert and key are optional
  forwarded_arguments.add_argument('--cert')
  forwarded_arguments.add_argument('--key')
  args = parser.parse_args()
  shared_part_list = [x.strip() for x in '''${buildout:shared-part-list}'''.splitlines() if x.strip()]
  partition_forward_configuration = (
      slapos.slap.standalone.PartitionForwardAsPartitionConfiguration(
          master_url=args.master_url,
          computer=args.computer,
          partition=args.partition,
          cert=args.cert,
          key=args.key,
          software_release_list=(
            'http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg',
          ),
      ),
  )
  standalone = slapos.slap.standalone.StandaloneSlapOS(
      args.base_directory,
      args.ipv4,
      args.server_port,
      computer_id=args.computer_id,
      shared_part_list=shared_part_list,
      software_root="%s/software" % args.base_directory,
      instance_root="%s/instance" % args.base_directory,
      partition_forward_configuration=partition_forward_configuration,
      slapos_bin="${buildout:bin-directory}/slapos",
  )
  standalone.start()
  partition_count = 20
  if len(glob.glob(os.path.join(standalone.instance_directory, '*'))) < partition_count:
    print("Standalone SlapOS: Formatting {partition_count} partitions".format(
        partition_count=partition_count))
    standalone.format(
        partition_count,
        args.ipv4,
        args.ipv6
    )
  print("Standalone SlapOS for computer `{}` started".format(args.computer_id))
  # Run instance at least once, to start the supervisor managing instances.
  try:
    standalone.waitForInstance(max_retry=0)
  except slapos.slap.standalone.SlapOSNodeCommandError as e:
    print("Error instanciating: {}".format(e))

  if args.sr:
    print("Supplying and Requesting Embedded Software {}".format(args.sr))
    standalone.supply(args.sr)
    standalone.request(args.sr, "Embedded Instance", args.srtype or None)

  quit_requested = []
  def signal_handler(signum, frame):
    print("Signal {signum} received".format(signum=signum))
    quit_requested.append(True)
  signal.signal(signal.SIGTERM, signal_handler)

  print("Standalone SlapOS ready")
  while not quit_requested:
    time.sleep(.1)

  print("Stopping standalone subsystem")
  standalone.stop()
  print("Exiting")
  sys.exit(0)

needs-these-eggs-scripts-in-path =
  ${supervisor:recipe}
  ${slapos-command:recipe}

[supervisor]
recipe = zc.recipe.egg
eggs =
  supervisor
  setuptools

[template-base]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:parts-directory}/${:_buildout_section_name_}
mode = 0644

[python-language-server]
version = 0.19.0
recipe = plone.recipe.command
command =
  PATH=${git:location}/bin/:$PATH  bash -c "${python3:executable} -m venv --clear ${:location} && \
    . ${:location}/bin/activate && \
    pip install -r ${python-language-server-requirements.txt:output}"
location = ${buildout:parts-directory}/${:_buildout_section_name_}
stop-on-error = true

[python-language-server-requirements.txt]
<= template-base

[theia]
recipe = plone.recipe.command
command = ${bash:location}/bin/bash -c "
  export TMPDIR=${:location}/tmp PATH=${nodejs:location}/bin:$PATH &&
  mkdir -p ${:location} && \
  mkdir -p \$TMPDIR && \
  cd ${:location} && \
  cp ${package.json:rendered} . &&
  cp ${yarn.lock:output} . &&
  ${yarn:location}/bin/yarn && \
  ${yarn:location}/bin/yarn theia build"
location = ${buildout:parts-directory}/${:_buildout_section_name_}
stop-on-error = true
uses = ${yarn.lock:recipe}

[theia-plugins]
recipe = slapos.recipe.build
urls = ${theia-download-plugins:urls}
install =
  import os
  for line in options['urls'].splitlines():
    extension_name, url, md5sum = line.split()
    extract_dir = self.extract(self.download(url, md5sum))
    destination_dir = os.path.join(options['location'], extension_name)
    self.copyTree(guessworkdir(extract_dir), destination_dir)
    os.chmod(destination_dir, 0o750)

[yarn.lock]
<= template-base

[preloadTemplate.html]
<= template-base

[slapos.css.in]
<= template-base

[logo.png]
<= template-base

[package.json]
recipe = slapos.recipe.template:jinja2
template =
  inline:{
      "private": true,
      "theia": {
          "frontend": {
              "config": {
                  "applicationName": "Theia SlapOS",
                  "preferences": {
                      "application.confirmExit": "always",
                      "files.associations": {
                          "*.cfg": "zc-buildout"
                      },
                      "files.enableTrash": false,
                      "files.exclude": {
                          "**.pyc": true,
                          "**.egg-info": true,
                          "__pycache__": true,
                          ".git": true,
                          ".env": true,
                          "**/node_modules/**": true
                      },
                      "files.watcherExclude": {
                          "**/.eggs/**": true,
                          "**/.env/**": true,
                          "**/.git/**": true,
                          "**/node_modules/**": true
                      },
                      "editor.multiCursorModifier": "ctrlCmd",
                      "editor.tabSize": 2,
                      "plantuml.server": "https://plantuml.host.vifib.net/svg/",
                      "plantuml.render": "PlantUMLServer",
                      "gitlens.remotes": [{ "domain": "lab.nexedi.com", "type": "GitLab" }],
                      "java.home": "${java-jdk:location}"
                  }
              }
          },
          "generator": {
              "config": {
                  "preloadTemplate": "${preloadTemplate.html:output}"
              }
          }
      },
      "dependencies": {
          "@theia/callhierarchy": "latest",
          "@theia/console": "latest",
          "@theia/core": "latest",
          "@theia/cpp-debug": "latest",
          "@theia/debug": "latest",
          "@theia/editor": "latest",
          "@theia/editor-preview": "latest",
          "@theia/file-search": "latest",
          "@theia/filesystem": "latest",
          "@theia/getting-started": "latest",
          "@theia/git": "latest",
          "@theia/keymaps": "latest",
          "@theia/markers": "latest",
          "@theia/messages": "latest",
          "@theia/metrics": "latest",
          "@theia/mini-browser": "latest",
          "@theia/monaco": "latest",
          "@theia/navigator": "latest",
          "@theia/outline-view": "latest",
          "@theia/output": "latest",
          "@theia/plugin": "latest",
          "@theia/plugin-ext": "latest",
          "@theia/plugin-ext-vscode": "latest",
          "@theia/preferences": "latest",
          "@theia/preview": "latest",
          "@theia/process": "latest",
          "@theia/scm": "latest",
          "@theia/search-in-workspace": "latest",
          "@theia/task": "latest",
          "@theia/terminal": "latest",
          "@theia/typehierarchy": "latest",
          "@theia/userstorage": "latest",
          "@theia/variable-resolver": "latest",
          "@theia/vsx-registry": "latest",
          "@theia/workspace": "latest",
          "@perrinjerome/theia-open": "latest",
          "@perrinjerome/theia-open-cli": "latest"
      },
      "devDependencies": {
          "@theia/cli": "latest"
      }
    }
rendered = ${buildout:directory}/${:_buildout_section_name_}
mode = 0644


[gowork]
install +=
   golang.org/x/tools/gopls@v0.6.6


[cli-utilities]
PATH = ${nodejs:location}/bin:${bash:location}/bin:${fish-shell:location}/bin:${tig:location}/bin:${vim:location}/bin:${tmux:location}/bin:${git:location}/bin:${curl:location}/bin:${python2.7:location}/bin:${buildout:bin-directory}


[theia-wrapper]
recipe = slapos.recipe.template:jinja2
rendered = ${buildout:bin-directory}/${:_buildout_section_name_}
mode = 0755
template =
  inline:
  #!/bin/sh
  cd ${theia:location}
  exec ${yarn:location}/bin/yarn theia start "$@"

[theia-open]
recipe = slapos.recipe.template:jinja2
rendered = ${buildout:bin-directory}/${:_buildout_section_name_}
mode = 0755
template =
  inline:
  #!/bin/sh
  exec ${nodejs:location}/bin/node ${theia:location}/node_modules/.bin/theia-open "$@"

[instance-theia]
<= template-base
output = ${buildout:directory}/instance-theia.cfg.jinja

[instance]
<= template-base
output = ${buildout:directory}/instance.cfg
