{% set parameter_dict = dict(default_parameter_dict, **slapparameter_dict) %}

# Create necessary directories.
[directory]
recipe = slapos.cookbook:mkdirectory
home = ${buildout:directory}
tmp = ${:home}/tmp
log = ${:home}/log
etc = ${:home}/etc
ssl = ${:etc}/ssl
service = ${:etc}/service

# Options for instance configuration. See README.md for a list of
# options that can be configured when requesting an instance.
[headless-chromium]
ipv4 = {{ partition_ipv4 }}
ipv6 = {{ partition_ipv6 }}
remote-debugging-port = {{ parameter_dict['remote-debugging-port'] }}
target-url = {{ parameter_dict['target-url'] }}
incognito = {{ parameter_dict['incognito'] }}
window-size = {{ parameter_dict['window-size'] }}
block-new-web-contents = {{ parameter_dict['block-new-web-contents'] }}
remote-debugging-address = ${:ipv4}:${:remote-debugging-port}
devtools-frontend-root = {{ parameter_list['devtools-frontend'] }}

nginx-port = {{ parameter_dict['nginx-proxy-port'] }}
proxy-address = [${:ipv6}]:${:nginx-port}
nginx-config-target = ${directory:etc}/nginx.conf
nginx-pid-path = ${directory:log}/nginx.pid
nginx-temp-path = ${directory:tmp}
nginx-error-log = ${directory:log}/nginx-error.log
nginx-access-log = ${directory:log}/nginx-access.log
nginx-htpasswd-file = ${directory:etc}/.htpasswd
nginx-key-file = ${frontend-instance-certificate:key-file}
nginx-cert-file = ${frontend-instance-certificate:cert-file}
nginx-mime-types = ${directory:etc}/mime-types


# Create a wrapper script in /bin/chromium for the headless shell
# executable.
[chromium-wrapper]
recipe = slapos.cookbook:wrapper
wrapper-path = ${directory:bin}/chromium
command-line =
  {{ parameter_list['chromium-wrapper'] }}
  --remote-debugging-address=${headless-chromium:ipv4}
  --remote-debugging-port=${headless-chromium:remote-debugging-port}
  --user-data-dir=${directory:tmp}
  --window-size="${headless-chromium:window-size}"
  {% if parameter_dict['incognito'] %}--incognito{% endif -%}
  {% if parameter_dict['block-new-web-contents'] %}--block-new-web-contents{% endif -%}
{{ '\n  "${headless-chromium:target-url}"' }}
environment =
  FONTCONFIG_FILE=${font-config:output}

[chromium-launcher]
recipe = slapos.cookbook:wrapper
command-line = ${chromium-wrapper:wrapper-path}
wrapper-path = ${directory:service}/chromium
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
hash-files = ${chromium-wrapper:wrapper-path}


# Configure and launch the proxy server.
[nginx-config]
recipe = slapos.recipe.template:jinja2
url = {{ parameter_list['template-nginx-config'] }}
output = ${headless-chromium:nginx-config-target}
context =
  section param_headless_chromium headless-chromium

[nginx-mime-types]
recipe = slapos.recipe.template
url = {{ parameter_list['template-mime-types'] }}
output = ${headless-chromium:nginx-mime-types}

[nginx-launcher]
recipe = slapos.cookbook:wrapper
command-line =
  {{ parameter_list['nginx-location'] }}/sbin/nginx
  -c ${headless-chromium:nginx-config-target}
wrapper-path = ${directory:service}/nginx

[logrotate-entry-nginx]
<= logrotate-entry-base
name = nginx
log = ${headless-chromium:nginx-error-log} ${headless-chromium:nginx-access-log}

[frontend-instance-password]
recipe = slapos.cookbook:generate.password
username = admin
bytes = 12

[generate-passwd-file]
recipe = plone.recipe.command
command =
  echo -n '${frontend-instance-password:username}:' > ${headless-chromium:nginx-htpasswd-file}
  openssl passwd -apr1 '${frontend-instance-password:passwd}' >> ${headless-chromium:nginx-htpasswd-file}
environment =
  PATH={{ parameter_list['openssl-location'] }}/bin:%(PATH)s

# Generate a self-signed TLS certificate.
[frontend-instance-certificate]
recipe = plone.recipe.command
command =
  if [ ! -e ${:key-file} ]
  then
    openssl req -x509 -nodes -days 3650 \
      -subj "/C=AA/ST=X/L=X/O=Dis/CN=${:common-name}" \
      -newkey rsa:1024 -keyout ${:key-file} \
      -out ${:cert-file}
    openssl x509 -addtrust serverAuth \
      -in ${:cert-file} \
      -out ${:cert-file}
  fi
update-command = ${:command}
key-file = ${directory:ssl}/${:_buildout_section_name_}.key
cert-file = ${directory:ssl}/${:_buildout_section_name_}.cert
common-name = ${headless-chromium:ipv6}
environment =
  PATH={{ parameter_list['openssl-location'] }}/bin:%(PATH)s


# Generate a fonts.conf file.
[font-config]
recipe = slapos.recipe.template:jinja2
url = {{ parameter_list['template-fonts-conf'] }}
output = ${directory:etc}/fonts.conf
context =
  key cachedir :cache-dir
  key fonts :fonts
  key includes :includes
cache-dir =
  ${directory:etc}/.fontconfig.cache
fonts =
  {{ parameter_list['liberation-fonts-location'] }}
includes =
  {{ parameter_list['fontconfig-location'] }}/etc/fonts/conf.d


[publish-connection-information]
recipe = slapos.cookbook:publish
<= monitor-publish
remote-debug-url = http://${headless-chromium:remote-debugging-address}
proxy-url = https://${headless-chromium:proxy-address}
frontend-url = ${remote-debugging-frontend:connection-secure_access}
username = ${frontend-instance-password:username}
password = ${frontend-instance-password:passwd}

# Request a frontend URL from the CDN for the remote debugging interface.
[remote-debugging-frontend]
<= slap-connection
recipe = slapos.cookbook:requestoptional
name = Headless Chromium Remote Debugging Frontend
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
slave = true
config-url = https://${headless-chromium:proxy-address}
config-https-only = true
config-type = websocket
config-websocket-path-list = /devtools
return = domain secure_access


# Monitoring: check that the Chromium process is alive and responding to
# requests through the proxy.
[monitor-instance-parameter]
monitor-httpd-port = {{ parameter_dict['monitor-httpd-port'] }}

# Promise to make sure the remote debugging frontend returns 200 when
# queried with the correct credentials.
[frontend-ok-promise]
<= monitor-promise-base
promise = check_url_available
name = headless-chromium-frontend-ok.py
url = ${remote-debugging-frontend:connection-secure_access}
config-url = ${:url}
config-username = ${frontend-instance-password:username}
config-password = ${frontend-instance-password:passwd}

# Promise to make sure that the remote debugging frontend returns 401
# when queried with no credentials.
[frontend-secure-promise]
<= monitor-promise-base
promise = check_url_available
name = headless-chromium-frontend-secure.py
url = ${remote-debugging-frontend:connection-secure_access}
config-url = ${:url}
config-http-code = 401

[buildout]
extends = {{ parameter_list['template-monitor'] }}

parts =
  chromium-launcher
  generate-passwd-file
  nginx-config
  nginx-mime-types
  nginx-launcher
  logrotate-entry-nginx
  remote-debugging-frontend
  publish-connection-information
  frontend-ok-promise
  frontend-secure-promise

eggs-directory = {{ buildout['eggs-directory'] }}
develop-eggs-directory = {{ buildout['develop-eggs-directory'] }}
offline = true
