import hudson.model.*
import jenkins.model.*

import java.util.logging.Logger
Logger logger = Logger.getLogger("ecs-cluster")

def env = System.getenv()
def j = Jenkins.getInstance()
def scripts_dir = env['JENKINS_HOME'] + '/init.groovy.d/'

def e = { filepath ->
  evaluate(new File(scripts_dir + filepath))
}

def mx = { filepath ->
  def script = new GroovyScriptEngine( '.' ).with {
    loadScriptByName( scripts_dir + filepath )
  }
  this.metaClass.mixin script
}

// New container have their all jobs nextBuildNumber=1 if it is restarted prior to deploy.
// Below will keep current build numbers.
def setNextBuildNumber = {
  jobs = Jenkins.instance.projects.collect { it.name }
  jobs.each() { job ->
    set_num = 0
    new File(env['JENKINS_HOME'] + '/jobs/' + job + '/builds').eachDir() { dir ->
      def thisdir = dir.getName().split("\\.")[0]
      if (thisdir.isNumber()) {
        if (thisdir.toInteger() > set_num) {
          set_num = thisdir.toInteger()
        }
      }
    }
    item = Jenkins.instance.getItemByFullName(job)
    item.updateNextBuildNumber(set_num + 1)
    item.save()
  }
}

Properties properties = new Properties()
try {
  properties.load(new FileInputStream(env['JENKINS_HOME'] + '/.groovy_init_required'))
  properties.load(new FileInputStream(scripts_dir + 'setup.properties'))
} catch (Exception err) {
  logger.info(' Check property files...')
  return 0
}

if (properties.CONTAINER_INIT_REQUIRED == null || properties.CONTAINER_INIT_REQUIRED != '1') {
  logger.info(' Groovy init not required...' + properties.CONTAINER_INIT_REQUIRED)
  return 0
}
new File(env['JENKINS_HOME'] + '/.groovy_init_required').delete()

///////////////////////////////////////////////////////////////////
///////////  Update proper build numbers for each job  ////////////
///////////////////////////////////////////////////////////////////
setNextBuildNumber()

///////////////////////////////////////////////////////////////////
///////////////////  E-mail Notification  /////////////////////////
///////////////////////////////////////////////////////////////////
if (properties.SMTP_HOST != null && properties.SMTP_HOST != '') {
  logger.info('++++ SET MAILER ' + properties.SMTP_HOST);
  def set_mailer = e('Module_Mailer')
  set_mailer(
    instance     = j,
    smtp_host    = properties.SMTP_HOST,
    replyto_addr = properties.REPLYTO_ADDR,
    email_suffix = ''
  )
  instance.save()
}

///////////////////////////////////////////////////////////////////
///////////////////  Location and Admin email  ////////////////////
///////////////////////////////////////////////////////////////////
if (properties.ADMIN_EMAIL != null && properties.ADMIN_EMAIL != '') {
  logger.info('++++ SET ADMIN_EMAIL ' + properties.ADMIN_EMAIL);
  def set_location_configuration = e('Module_LocationConfig')
  set_location_configuration(
    instance     = j,
    admin_email_addr = properties.ADMIN_EMAIL,
    location_url = properties.JENKINS_LOCATION_URL
  )
  instance.save()
}

///////////////////////////////////////////////////////////////////
////////////////////  LDAP configuration  /////////////////////////
///////////////////////////////////////////////////////////////////
if (properties.LDAP_ADDR != null && properties.LDAP_ADDR != '') {
  logger.info('++++ SET LDAP ' + properties.LDAP_ADDR);
  def configure_ldap       = e('Module_Ldap')
  configure_ldap(
    instance         = j,
    ldap_addr        = properties.LDAP_ADDR,
    ldap_rootDN      = properties.LDAP_ROOT_DN,
    ldap_managerDN   = properties.LDAP_MANAGER_DN,
    ldap_managerPass = properties.LDAP_MANAGER_PASS,
    ldap_userSearchBase  = properties.LDAP_USER_SEARCH_BASE,
    ldap_userSearch      = properties.LDAP_USER_SEARCH,
    ldap_groupSearchBase = properties.LDAP_GROUP_SEARCH_BASE
  )
  instance.save()
}

///////////////////////////////////////////////////////////////////
//////////////  Number of executors on Master node  ///////////////
///////////////////////////////////////////////////////////////////
if (properties.NUM_EXECUTORS != null && properties.NUM_EXECUTORS != '') {
  logger.info('++++ SET ECECUTORS ' + properties.NUM_EXECUTORS.toInteger());
  def set_num_executors    = e('Module_Executors')
  set_num_executors(
    instance = j,
    num      = properties.NUM_EXECUTORS.toInteger()
  )
  instance.save()
}

///////////////////////////////////////////////////////////////////
/////////////////////  SSH Credentials  ///////////////////////////
///////////////////////////////////////////////////////////////////
if (properties.CRED_LISTS != null && properties.CRED_LISTS != '') {
  def create_ssh_credential = e('Module_SshCredentials')
  properties.CRED_LISTS.eachLine { line ->
    oneline = line.split(/:/)
    id = oneline[0]
    configs = oneline[1].split(',')
    logger.info('++++ CREATE SSH CREDENTIAL ' + id + ' ' + configs);
    create_ssh_credential(
        instance       = j,
        id             = id,
        username       = configs[0],
        privateKeyFile = configs[1],
        description    = configs[2],
        passphrase     = ''
    )
    instance.save()
  }
}

///////////////////////////////////////////////////////////////////
//////////////////////  AWS Credentials  //////////////////////////
///////////////////////////////////////////////////////////////////
if (properties.CRED_AWS_ID != null && properties.CRED_AWS_ID != '') {
  logger.info('++++ CREATE AWS CREDENTIAL ' + properties.CRED_AWS_DESC);
  def create_aws_credential = e('Module_AwsCredentials')
  create_aws_credential(
    instance    = j,
    id          = properties.CRED_AWS_ID,
    accessKey   = properties.CRED_AWS_ACCESSKEY,
    secretKey   = properties.CRED_AWS_SECRETKEY,
    description = properties.CRED_AWS_DESC
  )
  instance.save()
}

///////////////////////////////////////////////////////////////////
///////////////////  Authorization strategy  //////////////////////
///////////////////////////////////////////////////////////////////
if (properties.USER_AUTH_MAP != null && properties.USER_AUTH_MAP != '') {
  logger.info('++++ SET AUTHORIZATION ');
  def set_matrix_authorization = e('Module_MatrixAuthorization')
  set_matrix_authorization(
    instance = j,
    user_mappings = properties.USER_AUTH_MAP
  )
  instance.save()
}

///////////////////////////////////////////////////////////////////
////////////////////////  Slave Nodes  ////////////////////////////
///////////////////////////////////////////////////////////////////
if (properties.NODES_LISTS != null && properties.NODES_LISTS != '') {
  def create_slave_node    = e('Module_Node')
  properties.NODES_LISTS.eachLine { line ->
    oneline = line.split(/:/)
    name = oneline[0]
    configs = oneline[1].split(',')
    logger.info('++++ CREATE SLAVE NODE ' + name + ' ' + configs);
    create_slave_node(
        instance = j,
        name           = name,
        remoteFS       = configs[0],
        numExecutors   = configs[1],
        labelString    = configs[2],
        sshHost        = configs[3],
        sshPort        = configs[4],
        sshCredentials = configs[5],
        userId         = configs[6]
    )
    instance.save()
  }
}

///////////////////////////////////////////////////////////////////
///////////////////////  Gerrit Trigger  //////////////////////////
///////////////////////////////////////////////////////////////////
if (properties.GERRIT_SERVER_NAME != null && properties.GERRIT_SERVER_NAME != '') {
  logger.info('++++ SET GERRIT TRIGGER ' + properties.GERRIT_HOST_NAME);
  def add_gerrit_trigger   = e('Module_GerritServer')
  add_gerrit_trigger(
    instance             = j,
    serverName           = properties.GERRIT_SERVER_NAME,
    noConnetionOnStartup = properties.GERRIT_NO_CONNECTION_ON_STARTUP.toBoolean(),
    gerritHostName       = properties.GERRIT_HOST_NAME,
    gerritSshPort        = properties.GERRIT_SSH_PORT,
    gerritUserName       = properties.GERRIT_USER_NAME,
    gerritAuthKeyFile    = properties.GERRIT_AUTH_KEYFILE,
    gerritFrontEndUrl    = properties.GERRIT_FRONTEND_URL
  )
  instance.save()
}

///////////////////////////////////////////////////////////////////
/////////////////////  Rabbitmq consumer  /////////////////////////
///////////////////////////////////////////////////////////////////
if (properties.RABBITMQ_SERVICE_URI != null && properties.RABBITMQ_SERVICE_URI != '') {
  logger.info('++++ SET RABBIT MQ CONSUMER ' + properties.RABBITMQ_SERVICE_URI);
  def set_rabbitmq = e('Module_RabbitmqConsumer')
  set_rabbitmq(
    instance       = j,
    enableConsumer = properties.RABBITMQ_ENABLE.toBoolean(),
    serviceUri     = properties.RABBITMQ_SERVICE_URI,
    userName       = properties.RABBITMQ_USER_NAME,
    userPassword   = properties.RABBITMQ_USER_PASSOWRD,
    applicationId  = properties.RABBITMQ_APP_ID,
    queueName      = properties.RABBITMQ_QUEUE_NAME
  )
  instance.save()
}

///////////////////////////////////////////////////////////////////
//////////////////////  Amazon EC2 Cloud  /////////////////////////
///////////////////////////////////////////////////////////////////
if (properties.AWS_CLOUD_NAME != null && properties.AWS_CLOUD_NAME != '') {
  logger.info('++++ SET AWS WORKERS ' + properties.EC2_AMI_ID);
  def ec2_workers = []
  def create_ec2_slave     = e('Module_AmazonEC2Slave')
  def create_ec2_cloud     = e('Module_AmazonEC2Cloud')
  create_ec2_slave(
    ami_id               = properties.EC2_AMI_ID,
    availability_zone    = properties.EC2_AV_ZONE,
    security_groups      = properties.EC2_SECURITY_GROUPS,
    remote_fs            = properties.EC2_REMOTE_FS,
    instance_type        = properties.EC2_INSTANCE_TYPE,
    labels               = properties.EC2_LABEL_STRING,
    description          = properties.EC2_DESCRIPTION,
    num_executors        = properties.EC2_NUMBER_OF_EXECUTORS,
    remote_user          = properties.EC2_REMOTE_ADMIN,
    subnet_id            = properties.EC2_SUBNET_ID,
    tag_name             = properties.EC2_TAG_NAME,
    tag_env              = properties.EC2_TAG_ENV,
    tag_hostname         = properties.EC2_TAG_HOSTNAME,
    tag_source           = properties.EC2_TAG_SOURCE,
    idle_termination     = properties.EC2_IDLE_TERMINATION_MINUTES,
    instance_cap         = properties.EC2_INSTANCE_CAP_STR,
    launch_timeout       = properties.EC2_LAUNCH_TIMEOUT,
    ec2_workers          = ec2_workers
  )

  create_ec2_cloud(
    instance             = j,
    cloud_name           = properties.AWS_CLOUD_NAME,
    cloud_credentials_id = properties.AWS_CLOUD_CREDENTIALS_ID,
    cloud_region         = properties.AWS_CLOUD_REGION,
    cloud_priv_key       = properties.AWS_CLOUD_PRIV_KEY_TXT,
    cloud_instance_cap   = properties.AWS_CLOUD_INSTANCE_CAP,
    ec2_workers          = ec2_workers
  )
  instance.save()
}

