class oci::sql::galera(
  $machine_hostname    = undef,
  $cluster_name        = undef,
  $machine_ip          = undef,
  $all_sql             = undef,
  $all_sql_ip          = undef,
  $first_sql           = undef,
  $pass_mysql_rootuser = undef,
  $pass_mysql_backup   = undef,
  $mysql_max_connections      = 10000,
  $mysql_max_user_connections = 5000,
){

  if $facts['os']['lsb'] != undef{
    $mycodename = $facts['os']['lsb']['distcodename']
  }else{
    $mycodename = $facts['os']['distro']['codename']
  }

  if $mycodename == 'stretch' or $mycodename == 'buster' {
    $galera_package_name = 'galera-3'
  }else{
    $galera_package_name = 'galera-4'
  }
  $ram_total_in_bytes = $facts['memory']['system']['available_bytes']
  $ram_total_in_gb = $ram_total_in_bytes / 1073741824
  $ram_total_in_gb_div_4 = $ram_total_in_gb / 4

  if $ram_total_in_gb_div_4 > 64 {
    $innodb_buffer_pool_size = 64
  }elsif $ram_total_in_gb_div_4 > 32{
    $innodb_buffer_pool_size = 32
  }elsif $ram_total_in_gb_div_4 > 16{
    $innodb_buffer_pool_size = 16
  }elsif $ram_total_in_gb_div_4 > 8{
    $innodb_buffer_pool_size = 8
  }elsif $ram_total_in_gb_div_4 > 4{
    $innodb_buffer_pool_size = 4
  }else{
    $innodb_buffer_pool_size = 2
  }

  package { 'mariadb-backup':
    ensure => present,
    before => Class['galera'],
  }

  $pre_trixie_options = {
        'ssl-disable'                     => true,
        'bind_address'                    => $machine_ip,
        'wait_timeout'                    => '28800',
        'interactive_timeout'             => '30',
        'connect_timeout'                 => '30',
        'character_set_server'            => 'utf8',
        'collation_server'                => 'utf8_general_ci',
        'innodb_buffer_pool_size'         => "${innodb_buffer_pool_size}G",
        'innodb_flush_log_at_trx_commit'  => '2',
        'max_connections'                 => "${mysql_max_connections}",
        'max_user_connections'            => "${mysql_max_user_connections}",
        'binlog_cache_size'               => '1M',
        'log-bin'                         => 'mysql-bin',
        'binlog_format'                   => 'ROW',
        'performance_schema'              => '1',
        'log_warnings'                    => '2',
        'wsrep_sst_auth'                  => "backup:${pass_mysql_backup}",
        'wsrep_sst_method'                => 'mariabackup',
        'wsrep_cluster_name'              => $cluster_name,
        'wsrep_node_name'                 => $machine_hostname,
        'wsrep_provider_options'          => 'cert.log_conflicts=YES;gcache.recover=yes;gcache.size=5G',
      }
  if $mycodename == 'stretch' or $mycodename == 'buster' or $mycodename == 'bullseye' or $mycodename == 'bookworm'{
    $mysqld_options = $pre_trixie_options
  }else{
    $mysqld_options = deep_merge($pre_trixie_options, { 'innodb_snapshot_isolation' => 'OFF' })
  }

  class { 'galera':
    galera_servers        => $all_sql_ip,
    galera_master         => $first_sql,
    mysql_package_name    => 'mariadb-server',
    client_package_name   => 'default-mysql-client',
    vendor_type           => 'mariadb',
    root_password         => $pass_mysql_rootuser,
    status_password       => $pass_mysql_rootuser,
    deb_sysmaint_password => $pass_mysql_rootuser,
    configure_repo        => false,
    configure_firewall    => false,
    galera_package_name   => $galera_package_name,
    override_options => {
      'mysqld' => $mysqld_options
    }
  }
  -> mysql_user { 'backup@%':
    ensure        => present,
    password_hash => mysql::password($pass_mysql_backup),
  }
  -> mysql_grant{'backup@%/*.*':
    ensure     => 'present',
    options    => ['GRANT'],
    privileges => ['BINLOG MONITOR', 'CREATE TEMPORARY TABLES', 'LOCK TABLES', 'PROCESS', 'RELOAD', 'SELECT', 'SHOW VIEW', 'TRIGGER'],
    table      => '*.*',
    user       => 'backup@%',
  }

  # Wait until SHOW STATUS LIKE 'wsrep_cluster_status' shows Primary
  -> exec {'galera-is-up':
    command => "/usr/bin/oci-wait-for-sql \"SHOW STATUS LIKE 'wsrep_cluster_status'\" Primary mysql 2800",
    unless  => '/bin/false # comment to satisfy puppet syntax requirements',
    require  => Class['galera'],
    timeout => 3000,
  }

  # Wait until SHOW STATUS LIKE 'wsrep_connected' shows ON
  exec {'galera-wsrep-connected-on':
    command => "/usr/bin/oci-wait-for-sql \"SHOW STATUS LIKE 'wsrep_connected'\" ON mysql 2800",
    unless  => '/bin/false # comment to satisfy puppet syntax requirements',
    require => Exec['galera-is-up'],
    timeout => 3000,
  }

  # Wait until SHOW STATUS LIKE 'wsrep_local_state_comment' shows Synced
  exec {'galera-is-synced':
    command => "/usr/bin/oci-wait-for-sql \"SHOW STATUS LIKE 'wsrep_local_state_comment'\" Synced mysql 280",
    unless  => '/bin/false # comment to satisfy puppet syntax requirements',
    require => Exec['galera-wsrep-connected-on'],
    timeout => 3000,
  }

  # Wait until all nodes are connected to the cluster
  $galera_cluster_num_of_nodes = sprintf('%i', $all_sql.size)
  exec {'galera-size-is-correct':
    command => "/usr/bin/oci-wait-for-sql \"SHOW STATUS LIKE 'wsrep_cluster_size'\" ${galera_cluster_num_of_nodes} mysql 2800",
    unless  => '/bin/false # comment to satisfy puppet syntax requirements',
    require => Exec['galera-is-synced'],
    timeout => 3000,
  }

}
