{% set part_list = [] -%}
{% macro section(name) %}{% do part_list.append(name) %}{{ name }}{% endmacro -%}
{% set use_ipv6 = slapparameter_dict.get('use-ipv6', True) -%}
{% set port = slapparameter_dict['tcp-port'] %}
{% set host = (ipv4_set | list)[0] -%}
{% if use_ipv6 -%}
{%   set ip = (ipv6_set | list)[0] -%}
{%   set host = '[' ~ ip ~ ']' -%}
{% else -%}
{%   set ip = (ipv4_set | list)[0] -%}
{% endif -%}
{% set dash = parameter_dict['dash-location'] ~ '/bin/dash' %}
{% set database_list = slapparameter_dict.get('database-list', [{'name': 'repdb', 'user': 'user', 'password': 'insecure'}]) -%}

# XXX- TODO: add cron with check db need restart then restart
# API check restard needed: http://repman/api/clusters/{clusterName}/servers/{serverName}/{serverPort}/need-restart

[{{ section('publish') }}]
recipe = slapos.cookbook:publish.serialised
-extends = publish-early
database-host = {{ host }}:{{ port }}
monitor-base-url = ${monitor-publish-parameters:monitor-base-url}
partition-path = ${buildout:directory}

[publish-early]
recipe = slapos.cookbook:publish-early
-init =
  server-id gen-server-id:value
{%- set server_id = slapparameter_dict.get('server-id') %}
{%- if server_id %}
server-id = {{ dumps(server_id) }}
{%- endif %}
database-list = {{ dumps(database_list) }}

[gen-server-id]
recipe = slapos.cookbook:random.integer
minimum = {{ dumps(1) }}
maximum = {{ dumps(2**32 - 1) }}

[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
mode = 644

[jinja2-template-executable]
< = jinja2-template-base
mode = 755

[simplefile]
< = jinja2-template-base
template = inline:{{ '{{ content }}' }}

{% macro simplefile(section_name, file_path, content, mode='') -%}
{%   set content_section_name = section_name ~ '-content' -%}
[{{  content_section_name }}]
content = {{ dumps(content) }}

[{{  section(section_name) }}]
< = simplefile
rendered = {{ file_path }}
context = key content {{content_section_name}}:content
mode = {{ mode }}
{%- endmacro %}

[my-cnf-parameters]
socket = ${directory:run}/mariadb.sock
ip = {{ ip }}
data-directory = ${directory:srv}/mariadb
pid-file = ${directory:run}/mariadb.pid
max-connection-count = {{ dumps(slapparameter_dict.get('max-connection-count', 1000)) }}
innodb-buffer-pool-size = {{ dumps(slapparameter_dict.get('innodb-buffer-pool-size', 0)) }}
innodb-buffer-pool-instances = {{ dumps(slapparameter_dict.get('innodb-buffer-pool-instances', 0)) }}
innodb-log-file-size = {{ dumps(slapparameter_dict.get('innodb-log-file-size', 0)) }}
innodb-file-per-table = {{ dumps(slapparameter_dict.get('innodb-file-per-table', 0)) }}
innodb-log-buffer-size = {{ dumps(slapparameter_dict.get('innodb-log-buffer-size', 0)) }}
relaxed-writes = {{ dumps(slapparameter_dict.get('relaxed-writes', False)) }}
server-id = ${publish-early:server-id}
ssl-crt = ${directory:mariadb-ssl}/crt.pem
ssl-key = ${directory:mariadb-ssl}/key.pem
ssl-ca-crt = ${certificate-authority:ca-dir}/cacert.pem

[my-cnf]
< = jinja2-template-base
rendered = ${directory:etc}/mariadb.cnf
template = {{ parameter_dict['template-my-cnf'] }}
context = section parameter_dict my-cnf-parameters

[init-root-sql]
< = jinja2-template-base
rendered = ${directory:etc}/.init-root.sql
template = {{ parameter_dict['template-mariadb-init-root'] }}
context = section parameter_dict init-script-parameters
mode = 600

[init-script-parameters]
password = {{ slapparameter_dict['root-password'] }}
database-list = {{ dumps(database_list) }}
root-user = repman

[init-script]
< = jinja2-template-executable
# XXX: is there a better location ?
rendered = ${directory:etc}/mariadb_initial_setup.sql
template = {{ parameter_dict['template-mariadb-initial-setup'] }}
context = section parameter_dict init-script-parameters

[update-mysql]
recipe = slapos.cookbook:generic.mysql.wrap_update_mysql
output = ${directory:bin}/mariadb_update
binary = ${binary-wrap-mysql_upgrade:wrapper-path}
mysql = ${binary-wrap-mysql:wrapper-path}
init-script = ${init-script:rendered}
mysql_tzinfo_to_sql = ${binary-wrap-mysql_tzinfo_to_sql:wrapper-path}

[{{ section('update-mysql-script') }}]
< = jinja2-template-executable
rendered = ${directory:scripts}/mariadb_update
init-password = ${directory:etc}/.init-passwd.done
upgrade-done = ${directory:lib}/mariadb-update-done
context =
  key init_password_done :init-password
  key upgrade_done       :upgrade-done
  key init_root_sql      init-root-sql:rendered
  key mysql_update       update-mysql:output
  raw mysql_conf         ${directory:etc}/mysql/my.cnf
  raw dash_bin           {{ dash }}
  raw mysql_bin          {{ parameter_dict['mariadb-location'] }}/bin/mysql
template = {{ parameter_dict['template-init-root-wrapper'] }}

[mysqld]
< = jinja2-template-executable
rendered = ${directory:bin}/mysqld
template = {{ parameter_dict['template-mysqld-wrapper'] }}
context =
  key defaults_file install-mysql-config:config
  key datadir my-cnf-parameters:data-directory
  key environ :environ
environ =
  ODBCSYSINI='${directory:etc}'
  LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}'{{ parameter_dict['unixodbc-location'] }}/lib'
  {%- for variable in slapparameter_dict.get('environment-variables', ()) %}
  {{ variable }}
  {%- endfor %}

[ca-mysqld]
<= certificate-authority
recipe = slapos.cookbook:certificate_authority.request
key-file = ${my-cnf-parameters:ssl-key}
cert-file = ${my-cnf-parameters:ssl-crt}
executable = ${mysqld:rendered}
wrapper = ${directory:controller}/mariadb

{% import "supervisord_lib" as supervisord_lib with context %}
{{ supervisord_lib.supervisord("mariadb-controller", buildout_bin_directory, supervisord_conf, use_service_hash=False) }}
{% do part_list.append("mariadb-controller-service") -%}
{% set maradb_program_dict = {"name": "mariadb", "command": "${ca-mysqld:wrapper}",
  "stopwaitsecs": 86400, "environment": []} %}

{{ supervisord_lib.supervisord_program("mariadb-controller", "mariadb", maradb_program_dict) }}
{% do part_list.append("mariadb-controller-mariadb") %}

[odbc-ini-text]
text = {{ dumps(slapparameter_dict.get('odbc-ini', '').encode('base64')) }}

[{{ section('odbc-ini') }}]
< = jinja2-template-base
rendered = ${directory:etc}/odbc.ini
template = inline:{% raw -%}
  {{ parameter_dict['text'].decode('base64') }}
  {%- endraw %}
context = section parameter_dict odbc-ini-text

# XXX - probably not needed anymore, to check
#[logrotate-entry-mariadb]
#< = logrotate-entry-base
#name = mariadb
#log = ${my-cnf-parameters:error-log} ${my-cnf-parameters:slow-query-log}
#post = "${binary-wrap-mysql:wrapper-path}" -B -e "FLUSH LOGS"

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

[binary-wrap-base]
recipe = slapos.cookbook:wrapper
# Note: --defaults-file must be the first argument, otherwise wrapped binary
# will reject it.
command-line = 
  "{{ parameter_dict['mariadb-location'] }}/bin/${:command}"
  --defaults-file="${directory:etc}/mysql/my.cnf" --protocol=socket ${:extra-args}
wrapper-path = ${directory:bin}/${:command}
extra-args =

[binary-wrap-mysql]
<= binary-wrap-base
command = mysql

[binary-wrap-mysqldump]
<= binary-wrap-base
command = mysqldump

[binary-wrap-mysql_upgrade]
<= binary-wrap-base
command = mysql_upgrade
extra-args = --skip-write-binlog

[binary-wrap-mysqladmin]
<= binary-wrap-base
command = mysqladmin

[binary-wrap-mysql_tzinfo_to_sql]
<= binary-wrap-base
command-line = "{{ parameter_dict['mariadb-location'] }}/bin/${:command}" --skip-write-binlog
command = mysql_tzinfo_to_sql

[binary-wrap-pt-digest]
<= binary-wrap-base
command-line = "{{ parameter_dict['percona-tools-location'] }}/bin/${:command}"
command = pt-query-digest


[directory]
recipe = slapos.cookbook:mkdirectory
bin = ${buildout:directory}/bin
etc = ${buildout:directory}/etc
scripts = ${:etc}/run
services = ${:etc}/service
controller = ${:etc}/controller
plugin = ${:etc}/plugin
srv = ${buildout:directory}/srv
tmp = ${buildout:directory}/tmp
backup = ${:srv}/backup
mariadb-backup-full = ${:backup}/mariadb-full
mariadb-backup-incremental = ${:backup}/mariadb-incremental
mariadb-ssl = ${:etc}/mariadb-ssl
var = ${buildout:directory}/var
lib = ${:var}/lib
mysql = ${:lib}/mysql
log = ${:var}/log
run = ${:var}/run
config-tmp = ${:tmp}/config
custom = ${directory:etc}/mysql/custom

[dbjob-parameter]
bash-bin = {{ bash_bin }}
db-user = ${init-script-parameters:root-user}
db-password = ${init-script-parameters:password}
mysql-dir = ${directory:mysql}
dbjob-cnf = ${directory:etc}/mysql/my.cnf
log-dir = ${directory:mysql}/.system/logs
tmp-dir = ${directory:tmp}
mysqld-socket  = ${my-cnf-parameters:socket}
socat-port = {{ port + 1 }}
restart-script = ${mysqld-restart-script:rendered}
socat-location = {{ parameter_dict['socat-location'] }}
mysql-location = {{ parameter_dict['mariadb-location'] }}
ip = {{ ip }}
port = {{ port }}

[dbjobs-executable]
< = jinja2-template-executable
rendered = ${directory:bin}/dbjobs
context =
  section parameter_dict dbjob-parameter
template = {{ parameter_dict['dbjobs-template'] }}

[{{ section('dbjobs-cron-entry') }}]
recipe = slapos.cookbook:cron.d
cron-entries = ${cron:cron-entries}
name = dbjobs
frequency = * * * * *
command = ${dbjobs-executable:rendered}

[mysqld-restart-script]
< = jinja2-template-executable
rendered = ${directory:bin}/mysqld_restart
template = inline:#!/bin/sh
  ${mariadb-controller-bin:wrapper-path} status
  ${mariadb-controller-bin:wrapper-path} restart mariadb
  sleep 1
  ${mariadb-controller-bin:wrapper-path} status

[{{ section('mariadb-need-start') }}]
recipe = slapos.cookbook:cron.d
cron-entries = ${cron:cron-entries}
name = mariadb-need-start
frequency = * * * * *
command = ${template-mysqld-need-start:rendered}

[template-mysqld-need-start]
< = jinja2-template-executable
rendered = ${directory:bin}/mysqld_need_start
template = {{ parameter_dict['template-mysqld-need-start'] }}
context =
  key mariadb_controller mariadb-controller-bin:wrapper-path
  raw username           {{ slapparameter_dict['repman-user'] }}
  raw repman_url         {{ slapparameter_dict['repman-url'] }}
  raw jq_bin             {{ jq_bin }}
  raw cluster            {{ slapparameter_dict['cluster'] }}
  raw db_host            {{ host }}
  raw db_port            {{ port }}
  raw bash_bin           {{ bash_bin }}
  raw curl_bin           {{ curl_bin }}

# Donwnload mariadb configuration from repman
[{{ section('install-mysql-config') }}]
recipe = plone.recipe.command
stop-on-error = true
cluster = {{ slapparameter_dict['cluster'] }}
config = ${directory:etc}/mysql/my.cnf
command =
  cd ${directory:config-tmp} &&
  {{ curl_bin }} -o config.tar.gz {{ slapparameter_dict['repman-url'] }}/api/clusters/${:cluster}/servers/{{ host }}/{{ port }}/config &&
  tar -xzf config.tar.gz &&
  cp -r data/.system ${directory:mysql} &&
  rm -rf ${directory:etc}/mysql &&
  cp -r etc/mysql ${directory:etc} &&
  ln -sf ${directory:mysql}/.system ${directory:var}/system &&
  ln -sf ${my-cnf:rendered} ${directory:etc}/mysql/custom/01_mariadb.cnf

update-command = ${:command}

[dash]
dash = {{ dumps(dash) }}

[{{ section('promise-check-computer-memory') }}]
<= monitor-promise-base
module = check_command_execute
name = check-computer-memory.py
config-command = "{{ parameter_dict["check-computer-memory-binary"] }}" -db ${monitor-instance-parameter:collector-db} --threshold "{{ slapparameter_dict["computer-memory-percent-threshold"] }}" --unit percent

[{{ section('promise') }}]
<= monitor-promise-base
module = check_command_execute
name = mariadb.py
config-command = "{{ parameter_dict['bin-directory'] }}/is-local-tcp-port-opened" "{{ ip }}" "{{ port }}"

[monitor-instance-parameter]
monitor-httpd-ipv6 = {{ (ipv6_set | list)[0] }}
monitor-httpd-port = {{ port + 1 }}
monitor-title = {{ slapparameter_dict['name'] }}
password = {{ slapparameter_dict['monitor-passwd'] }}

[buildout]
extends =
  {{ template_monitor }}
parts +=
  {{ part_list | join('\n  ') }}