#!/bin/bash

set -e
set -E

export LC_ALL=C.UTF-8

################################################################
# Load modules

configs="/etc/ngcp-installer/"
storage="/usr/share/ngcp-installer/"

if [[ ! -r "${configs}/config_deploy.inc" ]]; then
  log_die "Can not find ${configs}/config_deploy.inc file"
  exit 1
fi

# shellcheck source=./conf/config_deploy.inc
. "${configs}/config_deploy.inc"
# shellcheck source=./install/config_type.inc
. "${storage}/config_type.inc"
# shellcheck source=./install/config.inc
. "${storage}/config.inc"
# shellcheck source=./install/log.inc
. "${storage}/log.inc"
# shellcheck source=./install/interactive.inc
. "${storage}/interactive.inc"

if "${DEBUG_MODE}" ; then
  log_debug "Enabling ngcp-installer debug mode..."
  set -x
  export PS4='+\t (${BASH_SOURCE##*/}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): } '
fi

# shellcheck source=./install/system.inc
. "${storage}/system.inc"
# shellcheck source=./install/system_pro.inc
[ -f "${storage}/system_pro.inc" ] && . "${storage}/system_pro.inc"
# shellcheck source=./install/packages.inc
. "${storage}/packages.inc"
# shellcheck source=./install/mysql.inc
. "${storage}/mysql.inc"
# shellcheck source=./install/check.inc
. "${storage}/check.inc"
# shellcheck source=./install/cfg.inc
. "${storage}/cfg.inc"
# shellcheck source=./install/cfg_pro.inc
[ -f "${storage}/cfg_pro.inc" ] && . "${storage}/cfg_pro.inc"
# shellcheck source=./install/vm_services.inc
. "${storage}/vm_services.inc"
# shellcheck source=./install/ha.inc
[ -f "${storage}/ha.inc" ] && . "${storage}/ha.inc"

################################################################
# Check necessary defaults
if ! "${CE}" && ! "${PRO}" && ! "${CARRIER}" ; then
  log_error "NGCP system type is not defined, aborting"
  exit 1
fi

################################################################
# MAIN

: "${JOIN_CLUSTER:=false}"
: "${DOCKER_BUILD:=false}"
# For when we support pure Docker builds with services split per Dockerfile.
: "${DOCKER_PURE_BUILD:=false}"
: "${USE_EXISTING_YML:=}"
: "${MINIMAL:=false}"
declare -a USE_TUNING

args=$(getopt -n "$(basename "$0")" -o jh -l help,minimal,join,docker,use-existing-yml:,use-tuning: -- "$@")
eval set -- "${args}"
while true; do
  case "${1}" in
    -j|--join)
      JOIN_CLUSTER='true'
      shift
      ;;
    --docker)
      DOCKER_BUILD='true'
      shift
      ;;
    --use-existing-yml)
      USE_EXISTING_YML="${2}"
      shift 2
      ;;
    --use-tuning)
      USE_TUNING+=("${2}")
      shift 2
      ;;
    --minimal)
      MINIMAL='true'
      shift
      ;;
    -h|--help)
      system_usage
      exit 0
      ;;
    --)
      shift
      break
      ;;
    *)
      log_error "Unknown parameter '${1}'"
      exit 1
      ;;
  esac
done

cfg_validate_arguments
check_already_configured
system_print_begin

# trap signals: 1 SIGHUP, 2 SIGINT, 3 SIGQUIT, 6 SIGABRT, 15 SIGTERM
trap 'system_wait_exit;' 1 2 3 6 15 ERR EXIT

system_enable_deploy_status_server
system_set_deploy_status "initial-configuration"
show_network_configuration
check_terminal_multiplexer

system_create_steps_dir

run_func system_set_type
system_set_ngcp_hostname
system_set_ngcp_nodename

if "${PRO}" || "${CARRIER}" ; then
  cfg_set_host_peer_variables
  if "${CARRIER}" ; then
    system_set_ngcp_ha_role
  fi
fi

if "${JOIN_CLUSTER}" ; then
  run_func system_fix_resolv
  run_func check_sipwise_repo_connectivity
  run_func system_get_mgmt_ssh_config
  run_func cfg_restore_from_git_remote
  export USE_EXISTING_YML="config,constants,maintenance,network"
else
  # Create new YML files
  run_func cfg_schema_initialise
  # Update YML files
  run_func cfg_apply_cfg_schema
  run_func cfg_place_yml_files
  # Here commit "initial version of ngcpcfg on sp" is created in /etc/ngcp-config
  run_func cfg_ngcpcfg_initialise
  # Set common YML default values
  run_func cfg_common_configuration
fi

run_func system_stop_all_services

# If EXTERNAL_DEV virtual interface (vlan) set the
# variables to underlying network devices
run_func cfg_normalize_net_dev

if "${PRO}" || "${CARRIER}" ; then
  # Set PRO/Carrier YML default values, including network.yml
  run_func cfg_pro_configuration
  run_func cfg_build_configs "/etc/ngcp_mgmt_node"
  run_func cfg_build_net_configs
  run_func system_restart_network
  run_func cfg_generate_gluster_units
  run_func system_init_gluster_dirs
  run_func system_init_gluster_vol
elif "${CE}" ; then
  run_func cfg_set_network_config_ce
fi

run_func system_sync_time

if ! "${JOIN_CLUSTER}" ; then
  log_info 'Config changes (ngcpcfg diff) before commit "Save prepared configuration"'
  ngcpcfg diff
  # Here commit "Save prepared configuration" is created in /etc/ngcp-config
  run_func cfg_save_defaults#first_configuration "Save prepared configuration" "--no-db-sync"
fi

if "${PRO}" || "${CARRIER}" ; then
  if ! "${JOIN_CLUSTER}" ; then
    run_func cluster_init
  fi
fi

if "${PRO}" ; then
  run_func cfg_configure_macs
  # Here commit "Add MAC addresses of (sp1|sp2)" is created in /etc/ngcp-config
  run_func cfg_save_defaults#add_macs "Add MAC addresses of ${THIS_HOST}" "--no-db-sync"
fi

run_func cfg_cloud_tweaks

if "${PRO}" || "${CARRIER}" ; then
  run_func cfg_pxe_generate_known_hosts_template
fi

run_func cfg_physical_server_tweaks

# Here commit "changes for ngcp-panel keys" is created in /etc/ngcp-config
if ! "${JOIN_CLUSTER}" ; then
  run_func cfg_generate_ngcp_panel_keys
fi

# Here commit "Config files were created" is created in /etc/ngcp-config
# Build ngcp configs from templates for the first time
run_func cfg_build_templates
run_func cfg_systemctl_preset_all

run_func system_restart_ssh

run_func system_create_swapfile

# Here commit "changes for ssl certs" is created in /etc/ngcp-config
run_func cfg_generate_certs

if "${MINIMAL}" ; then
  run_func system_save_configured_time
  run_func system_print_done_configuration
  exit 0
fi

run_func mysql_mariadb_migration_configs
run_func mysql_create_instances

if "${PRO}" || "${CARRIER}" ; then
  if "${JOIN_CLUSTER}" ; then
    run_func mysql_restart_sync
  fi
  if "${CARRIER}" ; then
    run_func cfg_mysql_sync_grants_constants
    run_func mysql_sync_central_db
  fi
fi
if ! "${JOIN_CLUSTER}" ; then
  run_func mysql_sync_grants_constants
fi

if "${PRO}" || "${CARRIER}" ; then
  run_func cfg_prepare_pxe_configuration
fi

if "${PRO}" || "${CARRIER}" && ! "${JOIN_CLUSTER}" ; then
  run_func system_add_shared_name
  run_func cfg_ngcpcfg_init_shared
fi

# Here commit "--force-all-services Installer applying configuration" is created in /etc/ngcp-config
run_func cfg_apply_configs

if "${PRO}" || "${CARRIER}" ; then
  run_func system_start_monit
  if ! "${JOIN_CLUSTER}" ; then
    run_func system_wait_ha
  fi
  run_func cfg_fill_approx_cache
fi

if "${PRO}" || "${CARRIER}" ; then
  run_func cfg_push_configs_to_shared_storage
fi

if "${NGCPUPLOAD}" ; then
  run_func system_upload_translations
fi

run_func system_run_ngcp_eaddress

run_func system_save_configured_time

run_func system_print_done_configuration
