#!/bin/bash

## Init is run on host
## For now it is run every time the script is launched, but
## it should be launched only once after build.

## Accessible variables are:
## - SERVICE_NAME        Name of current service
## - DOCKER_BASE_IMAGE   Base image from which this service might be built if any
## - SERVICE_DATASTORE           Location on host of the DATASTORE of this service
## - SERVICE_CONFIGSTORE         Location on host of the CONFIGSTORE of this service

. lib/common

# Please note that postgres detect on its own if its datadir needs to be populated

service_def=$(get_compose_service_def "$SERVICE_NAME") || return 1
options="$(e "$service_def" | shyaml -y get-value options)" || true

SYNAPSE_OPTIONS=(

    server_name:string       ## The server name

    report_stats:bool        ## Enable anon stat reporting back to the Matrix project
    enable_registration:bool ## Enable registration on the Synapse instance.
    allow_guest_access:bool  ## allow guest joining this server.
    event_cache_size:size    ## event cache size [default 10K].
    max_upload_size:size     ## max upload size [default 10M].

    ## shared secrets
    registration_shared_secret:string  ## registrering users if registration is disable.
    macaroon_secret_key:string         ## secret for signing access tokens to the server.

    ## recaptcha
    recaptcha_public_key:string       ## required to have recaptcha upon registration
    recaptcha_private_key:string      ## required to have recaptcha upon registration
    enable_registration_captcha:bool  ## required to have recaptcha upon registration
    recaptcha_siteverify_api:string

    ## others
    soft_file_limit:numeric
    rc_messages_per_second:float
    rc_message_burst_count:float
    federation_rc_window_size:numeric
    federation_rc_sleep_limit:numeric
    federation_rc_sleep_delay:numeric
    federation_rc_reject_limit:numeric
    federation_rc_concurrent:numeric
    max_image_pixels:size
    dynamic_thumbnails:bool
    url_preview_enabled:bool
    max_spider_size:size
    bcrypt_rounds:numeric
    enable_group_creation:bool
    trusted_third_party_id_servers:sequence
    enable_metrics:bool
    room_invite_state_types:sequence
    expire_access_token:bool
    key_refresh_interval:string
    perspectives:struct
    password_config:struct

    ## NOT SUPPORTED YET
    #thumbnail_sizes

)

OPTIONS_CONCAT=" ${SYNAPSE_OPTIONS[*]} "

yaml_opts=()
while read-0 key val; do
    key_option="$key"
    case "$OPTIONS_CONCAT" in
        *" ${key_option}:bool "*)
            case "${val,,}" in
                true|ok|yes|y|1)
                    val="\"yes\""
                    ;;
                false|ko|nok|no|n|0)
                    val="\"no\""
                    ;;
                *)
                    die "Invalid value for ${WHITE}$key$NORMAL, please use a boolean value."
                    ;;
            esac
            ;;
        *" ${key_option}:numeric "*)
            if ! is_int "$val"; then
                die "Invalid value for ${WHITE}$key$NORMAL, please use numeric value."
            fi
            ;;
        *" ${key_option}:float "*)
            if ! is_float "$val"; then
                die "Invalid value for ${WHITE}$key$NORMAL, please use float value."
            fi
            ;;
        *" ${key_option}:struct "*)
            val_type=$(e "$val" | shyaml get-type) || return 1
            if [ "$val_type" != "struct" ]; then
                die "Invalid value for ${WHITE}$key$NORMAL, please use struct value."
            fi
            ;;
        *" ${key_option}:sequence "*)
            val_type=$(e "$val" | shyaml get-type) || return 1
            if [ "$val_type" != "sequence" ]; then
                die "Invalid value for ${WHITE}$key$NORMAL, please use sequence value."
            fi
            ;;
        *" ${key_option}:string "*)
            :
            ;;
        *" ${key_option}:size "*)
            [[ "${val}" =~ ^[0-9\.]+[KkMmGgTtPp]$ ]] || {
                die "Unknown size specification '${val}'."
            }
            ;;
        *)
            case "${key//_/-}" in
                *) die "Unknown option ${WHITE}$key$NORMAL.";;
            esac
            continue
            ;;
    esac
    yaml_opts+=("$key" "$val")
done < <(e "$options" | shyaml key-values-0)


setup_dirs || exit 1
cfg-base || exit 1
cfg-merge "$options" || exit 1


HOST_KEY_DIR=$SERVICE_DATASTORE$DATA_DIR/keys
for name_secret in registration_shared_secret macaroon_secret_key; do
    secret=$(e "$options" | shyaml -q get-value "$name_secret") || true
    if [ "$secret" == "None" ]; then
        secret=""
    fi

    coming_from_file=
    key_file="$HOST_KEY_DIR/${name_secret}.key"
    if [ -z "$secret" ]; then
        if [ -e "$key_file" ]; then
            secret="$(cat "$key_file")"
            coming_from_file=true
        else
            secret="$(gen_password 64)"
        fi
        cfg-merge "${name_secret}: \"$secret\"" || exit 1
    fi

    if [ -z "$coming_from_file" ]; then
        e "$secret" > "$key_file"
        chown -v "$uid:$gid" "$key_file" &&
        chmod -v 600 "$key_file" || exit 1
    fi
done


## XXXvlab: what to do with appservices ?
# environ["SYNAPSE_APPSERVICES"] = glob.glob("/data/appservices/*.yaml")
# {% if SYNAPSE_APPSERVICES %}
# app_service_config_files:
# {% for appservice in SYNAPSE_APPSERVICES %}    - "{{ appservice }}"
# {% endfor %}
# {% else %}
# app_service_config_files: []
# {% endif %}

# ## Turn ##

# {% if SYNAPSE_TURN_URIS %}
# turn_uris:
# {% for uri in SYNAPSE_TURN_URIS.split(',') %}    - "{{ uri }}"
# {% endfor %}
# turn_shared_secret: "{{ SYNAPSE_TURN_SECRET }}"
# turn_user_lifetime: "1h"
# turn_allow_guests: True
# {% else %}
# turn_uris: []
# turn_shared_secret: "YOUR_SHARED_SECRET"
# turn_user_lifetime: "1h"
# turn_allow_guests: True
# {% endif %}

## XXXvlab: for SMTP relation
# {% if SYNAPSE_SMTP_HOST %}
# email:
#    enable_notifs: false
#    smtp_host: "{{ SYNAPSE_SMTP_HOST }}"
#    smtp_port: {{ SYNAPSE_SMTP_PORT or "25" }}
#    smtp_user: "{{ SYNAPSE_SMTP_USER }}"
#    smtp_pass: "{{ SYNAPSE_SMTP_PASSWORD }}"
#    require_transport_security: False
#    notif_from: "{{ SYNAPSE_SMTP_FROM or "hostmaster@" + SYNAPSE_SERVER_NAME }}"
#    app_name: Matrix
#    # if template_dir is unset, uses the example templates that are part of
#    # the Synapse distribution.
#    #template_dir: res/templates
#    notif_template_html: notif_mail.html
#    notif_template_text: notif_mail.txt
#    notif_for_new_users: True
#    riot_base_url: "https://{{ SYNAPSE_SERVER_NAME }}"
# {% endif %}