{% if slap_software_type == software_type -%}
{% set use_ipv6 = slapparameter_dict.get('use-ipv6', False) -%}
{% set next_port = slapparameter_dict['port-base'] -%}
{% set site_id = slapparameter_dict['site-id'] -%}
{% set storage_type = slapparameter_dict['zodb-storage-type'] -%}
{% set part_list = [] -%}
{% set publish_list = [] -%}
{% set zodb_dict = slapparameter_dict['zodb-dict'] -%}
{% set longrequest_logger_base_path = buildout_directory ~ '/var/log/longrequest_logger_' -%}
{% macro section(name) %}{% do part_list.append(name) %}{{ name }}{% endmacro -%}
{% set bin_directory = parameter_dict['buildout-bin-directory'] -%}
{#
XXX: This template only supports exactly one IPv4 and one IPv6 per
partition. No more (undefined result), no less (IndexError).
-#}
{% set ipv4 = (ipv4_set | list)[0] -%}

{% if slapparameter_dict['mysql-test-url-list'] -%}
[{{ section('test-runner') }}]
recipe = slapos.cookbook:erp5.test
certificate-authority-path = ${test-certificate-authority:ca-dir}
mysql-url-list = {{ dumps(slapparameter_dict['mysql-test-url-list']) }}
kumofs-url = {{ dumps(slapparameter_dict['kumofs-url']) }}
memcached-url = {{ dumps(slapparameter_dict['memcached-url']) }}
cloudooo-url = {{ dumps(slapparameter_dict['cloudooo-url']) }}
test-instance-path = ${directory:unit-test-path}
prepend-path = ${buildout:bin-directory}
run-unit-test = ${buildout:bin-directory}/runUnitTest
run-test-suite = ${buildout:bin-directory}/runTestSuite
openssl-binary = ${test-certificate-authority:openssl-binary}
run-unit-test-binary = {{ parameter_dict['bin-directory'] }}/runUnitTest
run-test-suite-binary = {{ parameter_dict['bin-directory'] }}/runTestSuite

[test-certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = ${binary-link:target-directory}/openssl
ca-dir = ${directory:test-ca-dir}
requests-directory = ${directory:test-ca-requests}
wrapper = ${directory:services}/test-ca
ca-private = ${directory:test-ca-private}
ca-certs = ${directory:test-ca-certs}
ca-newcerts = ${directory:test-ca-newcerts}
ca-crl = ${directory:test-ca-crl}
{%- endif %}

[directory]
recipe = slapos.cookbook:mkdirectory
bin = ${buildout:directory}/bin
etc = ${buildout:directory}/etc
instance = ${:srv}/erp5shared
instance-constraint = ${:instance}/Constraint
instance-document = ${:instance}/Document
instance-etc = ${:instance}/etc
instance-etc-package-include = ${:instance}/etc/package-include
instance-extensions = ${:instance}/Extensions
instance-import = ${:instance}/import
instance-lib = ${:instance}/lib
instance-products = ${:instance}/Products
instance-propertysheet = ${:instance}/PropertySheet
instance-tests = ${:instance}/tests
log = ${:var}/log
run = ${:var}/run
services = ${:etc}/run
srv = ${buildout:directory}/srv
tmp = ${buildout:directory}/tmp
var = ${buildout:directory}/var
promises = ${:etc}/promise
unit-test-path = ${:srv}/test-instance/unit_test
test-ca-dir = ${:srv}/test-ca
test-ca-requests = ${:test-ca-dir}/requests
test-ca-private = ${:test-ca-dir}/private
test-ca-certs = ${:test-ca-dir}/certs
test-ca-newcerts = ${:test-ca-dir}/newcerts
test-ca-crl = ${:test-ca-dir}/crl
ca-dir = ${:srv}/ca
ca-requests = ${:ca-dir}/requests
ca-private = ${:ca-dir}/private
ca-certs = ${:ca-dir}/certs
ca-newcerts = ${:ca-dir}/newcerts
ca-crl = ${:ca-dir}/crl

[binary-link]
recipe = slapos.cookbook:symbolic.link
target-directory = ${directory:bin}
link-binary = {{ dumps(parameter_dict['link-binary']) }}

[certificate-authority-common]
requests-directory = ${directory:ca-requests}
ca-dir = ${directory:ca-dir}
ca-private = ${directory:ca-private}
ca-certs = ${directory:ca-certs}
ca-newcerts = ${directory:ca-newcerts}
ca-crl = ${directory:ca-crl}

[{{ section('certificate-authority') }}]
< = certificate-authority-common
recipe = slapos.cookbook:certificate_authority
openssl-binary = ${binary-link:target-directory}/openssl
wrapper = ${directory:services}/ca

{% if use_ipv6 -%}
{%   set ipv6 = (ipv6_set | list)[0] -%}
[zeo-tunnel-base]
recipe = slapos.cookbook:ipv4toipv6
runner-path = ${directory:services}/${:base-name}
6tunnel-path = {{ parameter_dict['6tunnel'] }}/bin/6tunnel
shell-path = {{ parameter_dict['dash'] }}/bin/dash
ipv4 = {{ ipv4 }}

{%   if storage_type == 'zeoclient' -%}
{#     ZEO needs tunelling for IPv6 (...until next version becomes current in Zope) -#}
{%     set zeo_tunneling_dict = {} -%}
{%     for _, _, storage_dict in zodb_dict.values() -%}
{%       set storage_server = storage_dict['server'] -%}
{%       if storage_server not in zeo_tunneling_dict -%}
{%         set current_port = next_port + (zeo_tunneling_dict | length) -%}
{%         do zeo_tunneling_dict.__setitem__(storage_server, current_port) -%}
[{{ section('zeo-tunnel-' ~ current_port) }}]
< = zeo-tunnel-base
base-name = {{ 'zeo-tunnel-' ~ current_port }}
ipv4-port = {{ current_port }}
ipv6-port = {{ storage_server.split(']:')[1] }}
ipv6 = {{ storage_server.split(']:')[0][1:] }}
{%       endif -%}
{%       do storage_dict.__setitem__('server', '' ~ ipv4 ~ ':' ~ zeo_tunneling_dict[storage_server]) -%}
{%     endfor -%}
{%     set next_port = next_port + (zeo_tunneling_dict | length) -%}
{%   endif -%}
{%   if slapparameter_dict.get('tidstorage-ip') -%}
[tidstorage-tunnel]
< = zeo-tunnel-base
base-name = tidstorage-tunnel
ipv4-port = {{ next_port }}
ipv6 = {{ dumps(slapparameter_dict.get('tidstorage-ip')) }}
ipv6-port = {{ dumps(slapparameter_dict.get('tidstorage-port')) }}
{%     do slapparameter_dict.__setitem__('tidstorage-ip', ipv4) -%}
{%     do slapparameter_dict.__setitem__('tidstorage-port', next_port) -%}
{%     set next_port = next_port + 1 -%}

[{{ section("promise-tidstorage-tunnel") }}]
recipe = slapos.cookbook:check_port_listening
hostname = ${tidstorage-tunnel:ipv4}
port = ${tidstorage-tunnel:ipv4-port}
path = ${directory:promises}/tidstorage
{%   endif -%}

[ipv6toipv4-base]
recipe = slapos.cookbook:ipv6toipv4
runner-path = ${directory:services}/${:base-name}
6tunnel-path = {{ parameter_dict['6tunnel'] }}/bin/6tunnel
shell-path = {{ parameter_dict['dash'] }}/bin/dash
ipv4 = {{ ipv4 }}
ipv6 = {{ ipv6 }}
{% endif -%}

{% if slapparameter_dict.get('tidstorage-ip') -%}
[tidstorage]
ipv4 = {{ dumps(slapparameter_dict['tidstorage-ip']) }}
ipv4-port = {{ dumps(slapparameter_dict['tidstorage-port']) }}
{% else -%}
[tidstorage]
ipv4 =
ipv4-port =
{% endif -%}

[zope-base]
recipe = slapos.cookbook:generic.zope.zeo.client
user = {{ dumps(slapparameter_dict['inituser-login']) }}
password = {{ dumps(slapparameter_dict['inituser-password']) }}
ip = {{ ipv4 }}
timezone = {{ dumps(slapparameter_dict['timezone']) }}
tidstorage-ip = ${tidstorage:ipv4}
tidstorage-port = ${tidstorage:ipv4-port}
instance-etc = ${directory:instance-etc}
bt5-repository = ${directory:var}/bt5_repository
tmp-path = ${directory:tmp}
bin-path = ${directory:bin}
site-zcml = ${:instance-etc}/site.zcml
inituser = ${directory:instance}/inituser
runzope-binary = {{ bin_directory }}/runzope
bt5-repository-list =

[zope-conf-parameter-base]
ip = {{ ipv4 }}
site-id = {{ site_id }}
{% set zodb_list = [] -%}
{% for key, (mount_point, cache_size, storage_dict) in zodb_dict.items() -%}
{%   do zodb_list.append([key, mount_point, cache_size, storage_type, storage_dict]) -%}
{% endfor -%}
zodb-list = {{ dumps(zodb_list) }}
developer-list = {{ dumps(slapparameter_dict['developer-list']) }}

[zope-conf-base]
recipe = slapos.recipe.template:jinja2
template = {{ parameter_dict['zope-conf-template'] }}
extra-context =
context =
  key instance directory:instance
  key instance_products directory:instance-products
  raw deadlock_path /manage_debug_threads
  raw deadlock_debugger_password {{ dumps(slapparameter_dict['deadlock-debugger-password']) }}
  key tidstorage_ip tidstorage:ipv4
  key tidstorage_port tidstorage:ipv4-port
  key promise_path erp5-promise:promise-path
  ${:extra-context}

[logrotate-entry-base]
recipe = slapos.cookbook:logrotate.d
logrotate-entries = ${logrotate:logrotate-entries}
backup = ${logrotate:backup}

{% macro zope(
  name,
  port,
  thread_amount,
  timerserver_interval,
  longrequest_logger_timeout,
  longrequest_logger_interval
) -%}
{% set conf_name = name ~ '-conf' -%}
{% set conf_parameter_name = conf_name ~ '-param' -%}
{% set zope_tunnel_section_name = name ~ '-ipv6toipv4' -%}
{% set zope_tunnel_base_name = zope_tunnel_section_name -%}
[{{ conf_parameter_name }}]
< = zope-conf-parameter-base
pid-file = ${directory:run}/{{ name }}.pid
lock-file = ${directory:run}/{{ name }}.lock
port = {{ port }}
thread-amount = {{ thread_amount }}
timerserver-interval = {{ dumps(timerserver_interval) }}
event-log = ${directory:log}/{{ name }}-event.log
z2-log = ${directory:log}/{{ name }}-Z2.log

[{{ conf_name }}]
< = zope-conf-base
rendered = ${directory:etc}/{{ name }}.conf
extra-context =
  section parameter_dict {{ conf_parameter_name }}

[{{ name }}]
< = zope-base
{% if longrequest_logger_interval < 0 -%}
longrequest-logger-file =
longrequest-logger-timeout =
longrequest-logger-interval =
{% else -%}
longrequest-logger-file = {{ longrequest_logger_base_path ~ name ~ ".log" }}
longrequest-logger-timeout = {{ longrequest_logger_timeout }}
longrequest-logger-interval = {{ longrequest_logger_interval }}
{% endif -%}
wrapper = ${directory:services}/{{ name }}
configuration-file = {{ '${' ~ conf_name ~ ':rendered}' }}
port = {{ '${' ~ conf_parameter_name ~ ':port}' }}

[{{ section("promise-" ~ name) }}]
recipe = slapos.cookbook:check_port_listening
hostname = {{ '${' ~ name ~ ':ip}' }}
port = {{ '${' ~ name ~ ':port}' }}
path = ${directory:promises}/{{ name }}

{% if use_ipv6 -%}
[{{ zope_tunnel_section_name }}]
< = ipv6toipv4-base
base-name = {{ zope_tunnel_base_name }}
ipv6-port = {{ port }}
ipv4-port = {{ port }}
{%   do publish_list.append(("[" ~ ipv6 ~ "]:" ~ port, thread_amount)) -%}

[{{ section("promise-tunnel-" ~ name) }}]
recipe = slapos.cookbook:check_port_listening
hostname = {{ '${' ~ zope_tunnel_section_name ~ ':ipv6}' }}
port = {{ '${' ~ zope_tunnel_section_name ~ ':ipv6-port}' }}
path = ${directory:promises}/{{ zope_tunnel_base_name }}
{% else -%}
{%   do publish_list.append((ipv4 ~ ":" ~ port, thread_amount)) -%}
{% endif -%}

[{{ section('logrotate-entry-' ~ name) }}]
< = logrotate-entry-base
name = {{ name }}
log = {{ '${' ~ conf_parameter_name ~ ':event-log}' }} {{ '${' ~ conf_parameter_name ~ ':z2-log}' }} {{ '${' ~ name ~ ':longrequest-logger-file}' }}
post = {{ bin_directory }}/killpidfromfile {{ '${' ~ conf_parameter_name ~ ':pid-file}' }} SIGUSR2
{% endmacro -%}

{% for i in range(slapparameter_dict.get('instance-count', 1)) -%}
{{   zope("zope-" ~ i, next_port, slapparameter_dict['thread-amount'], slapparameter_dict['timerserver-interval'], slapparameter_dict['longrequest-logger-timeout'], slapparameter_dict['longrequest-logger-interval']) }}
{%   set next_port = next_port + 1 -%}
{% endfor -%}

[publish-zope]
recipe = slapos.cookbook:publish.serialised
zope-address-list = {{ dumps(publish_list) }}

[erp5-promise]
recipe = slapos.cookbook:erp5.promise
promise-path = ${directory:etc}/erp5promise.cfg
kumofs-url = {{ dumps(slapparameter_dict['kumofs-url']) }}
memcached-url = {{ dumps(slapparameter_dict['memcached-url']) }}
cloudooo-url = {{ dumps(slapparameter_dict['cloudooo-url']) }}
smtp-url = {{ dumps(slapparameter_dict['smtp-url']) }}
bt5 = {{ dumps(slapparameter_dict['bt5']) }}
bt5-repository-url = {{ dumps(slapparameter_dict['bt5-repository-url']) }}

[buildout]
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
extends =
  {{ parameter_dict['instance-logrotate-cfg'] }}
parts +=
  erp5-promise
  {{ part_list | join('\n  ') }}
  publish-zope
versions = versions

[versions]
slapos.core = {{ slapos_core_version }}
{% endif %}