#
# Cookbook:: irrigate-apache
# Recipe:: slaughterhouse
#
# Copyright:: The Orchard
#

slaughterhouse_root_directory = node['slaughterhouse']['root_directory']

packages = %w(
  git
  unzip
  zip
)

if platform_family?('rhel')
  if node['platform_version'].start_with?('7')

    packages += %w(
      python3
    )

    packages.each do |name|
      package name
    end

    python_packages = %w(
      setuptools
      awscli
    )

    python_packages.each do |name|
      execute 'install_python_package' do
        command "pip3 install #{name}"
        user 'root'
        not_if "pip3 show #{name} | awk 'NR==1 {print $2}' | grep -q #{name}"
      end
    end

    # This behavior appears to be different with EL7 and Chef < 18
    directory slaughterhouse_root_directory do
      owner node['php']['deploy_user']
      group node['slaughterhouse']['application_directory_group']
      mode '0775'
      action :create
    end

    # Ensure the default vhost is disabled
    apache_site 'default' do
      enabled false
    end

    php_engine_binary = '/opt/remi/php56/root/usr/bin/php'
  end
elsif platform_family?('debian')

  packages += %w(
    awscli
  )

  packages.each do |name|
    package name
  end

  # git resource will silently fail if directory exists, so remove it
  # https://github.com/chef/chef/issues/7347
  directory slaughterhouse_root_directory do
    action :delete
    recursive true
    not_if { Dir.exist?("#{slaughterhouse_root_directory}/slaughterhouse") }
  end

  directory File.dirname(slaughterhouse_root_directory) do
    owner node['php']['deploy_user']
    group node['slaughterhouse']['application_directory_group']
    mode '0775'
  end

  default_sites = %w(
    000-default
    default
  )

  default_sites.each do |site|
    # Ensure the default vhost is disabled
    apache_site site do
      enabled false
    end
  end

  php_engine_binary = 'php'
end

git 'Slaughterhouse' do
  repository 'git@github.com:theorchard/bacon.git'
  checkout_branch node['slaughterhouse']['git_branch']
  enable_checkout false
  destination slaughterhouse_root_directory
  user node['php']['deploy_user']
  group node['slaughterhouse']['application_directory_group']
  action :checkout
end

# Slaughterhouse SFTP user
slaughterhouse_sftp_user = node['slaughterhouse']['sftp_user']
home_directory = node['slaughterhouse']['sftp_user_home_directory']

user slaughterhouse_sftp_user do
  comment 'Slaughterhouse SFTP user'
  home home_directory
  manage_home true
  shell '/sbin/nologin'
end

cron "update_#{slaughterhouse_sftp_user}_password" do
  weekday 3
  hour 0
  minute 30
  command "echo #{slaughterhouse_sftp_user}:$(openssl rand -base64 24) | chpasswd"
end

directory home_directory do
  owner 'root'
  group slaughterhouse_sftp_user
  mode '0755'
end

ssh_authorize_key 'bgarcia@theorchard.com' do
  key 'AAAAB3NzaC1yc2EAAAADAQABAAACAQC8LHOWeJJtcY+Eg80fbQxZwqZxb8ELv1hR5otcmyzjJLnSlpc8CyUZ93KMX4n8RNpV1QmN3oiCMMViwM8FGApbN6t8DonJtXWOB++Et/LdFE00/kD6Y8ZEw4oI7rCc/0Ov4zdrPQwMahJvNPYb/Vg9AgC9ZMufIoRk02+Da12gYmRFWmvUyvN8rX9eAHu/0p74rfO0zi1YyidqctrvavPrQBhtx4aa+l8Zim507oDEzfmnAuzGXO6c052FZNxO+gQhTLWZbQie4WxviA36Rcov/SI1WhHCWgMWRszZXJDghNLudGGM6ticXggD9nZjYu7N0bAZvKvVKUc+sOIOfOd5UhIgUFTWQUmlo509NpPup01Erc9v+qmV0vCoeWk56QjB3oMqNrwsVPEWWQBBhaHxxMZN++xiVn+Fv4bfCDzrIgT6f/h6TyP9Wx0u7xUYXz/UaVPN3/YOBWnpYTHV71ZIA8v820AJ38rJSIkHmbn8LrwXA8hecI57On/TPWlq33Z9AHwhyTKOyAawf6rrkSV37MD4zRwI+27ltxh0vv9nh+y0Xwa9BGGcx0Y8Jm2BTZKr1Iqscu9X/gakysDI2x/vboR3JN+hTfvG9m30OmnREumfropXrzhRJJN0pPxnSHWdgU2aUv5KkBz221TSAHEM1dXBtBRcXER3DUBW76uGRQ=='
  user slaughterhouse_sftp_user
end

ssh_authorize_key 'jkass@theorchard.com' do
  key 'AAAAB3NzaC1yc2EAAAADAQABAAACAQCgI2sDGoxcwjrcJzLZO1Aoy8esyKNmP6zDRcsEp+4b/DJfq3BdtnmClecjDjEyu8oQc3G/aZt/O7HoWvfhAuOn+y5ejl8znYRZL7PXklFK7ZbwiC5Vsjg8uu/1cvRxhyGhwc6AiUVqHlrP5uZHrUaGyVH9hAL39ez5MRbJWLz680248i/WnFqnuUeOlbzYBL7Ur0tk0o6twTetTBrlnjSLMbwcu9sENRNPOHkLkB74vtUNBl9mH5g6nnm2wZ8EOxlj2CopmFXMfqCBm8UTrxCGvHFz9u7NA0bx1kVaoIBrFp2EsIQ+NiET4cPM9CDrjRrB2fntyBNcxad8HF4EuXJWVvmGOA377MSFsenHM7/jis1qQYN3uC6JRReLEvH06b6JDZPuFdOCw4k7T2iHCWQmlV+xaD4BWoIfnc1mghWNraN75IXTPMb/Wcs7+xNVSwwZoIpASlrIpbGqlJKKkmtvCnze7CLyc6NgEfavct8JbJIQUdtfBnt85uyV/7A5D2669qjf4Q1jZI02wRbl5D0FF3LXAnRLAXoiGpvLrbGoEdCiaylMFT/pUFWsNsMK3zdzn8y/FhqxmObXlTT4jeIHARt9MuFQKHJcIJFFMPj8nqu0iJ/uiSOHlagdcvS7vKwOLDdzHG6P7qjfiSG3TDObygiJDdjEoRLg5kgb/dveqQ=='
  user slaughterhouse_sftp_user
end

# Ensure options from user_ssh recipe in irrigate-orchard_base persist
node.override['sshd']['sshd_config']['PermitRootLogin']        = 'yes'
node.override['sshd']['sshd_config']['PasswordAuthentication'] = 'no'
node.override['sshd']['sshd_config']['Match'] = {
  "User #{slaughterhouse_sftp_user}" => {
    'ChrootDirectory' => home_directory,
    'ForceCommand' => 'internal-sftp',
    'AllowTcpForwarding' => 'no',
    'X11Forwarding' => 'no',
  },
}

include_recipe 'sshd::default'

# Slaughterhouse has several hard-coded directory paths, so stub them out
slaughterhouse_sftp_directories = %W(
  #{home_directory}/dropbox
  #{home_directory}/dropbox/trash
)

# The SFTP user drops files in them, as does browser upload
slaughterhouse_sftp_directories.each do |slaughterhouse_directory|
  directory slaughterhouse_directory do
    mode '0775'
    owner slaughterhouse_sftp_user
    group node['apache']['group']
    recursive true
  end
end

# Symlink dropbox directory into chrooted SFTP drop directory
link "#{slaughterhouse_root_directory}/slaughterhouse/dropbox" do
  to "#{home_directory}/dropbox"
end

# Populate healthcheck
file "#{slaughterhouse_root_directory}/healthchk.html" do
  content 'hello'
  owner node['php']['deploy_user']
  group node['slaughterhouse']['application_directory_group']
  mode '644'
  action :create
end

if node['slaughterhouse']['db_credentials_data_bag_name'] && !node['slaughterhouse']['db_credentials_data_bag_name'].empty?
  slaughterhouse_database_credentials = data_bag_item('secrets', node['slaughterhouse']['db_credentials_data_bag_name'])
  statement_db_host = slaughterhouse_database_credentials['statement_db_host'].chomp
  statement_db_user = slaughterhouse_database_credentials['statement_db_user'].chomp
  statement_db_password = slaughterhouse_database_credentials['statement_db_password'].chomp
  statement_db_name     = slaughterhouse_database_credentials['statement_db_name'].chomp
  ar_db_host            = slaughterhouse_database_credentials['ar_db_host'].chomp
  ar_db_user            = slaughterhouse_database_credentials['ar_db_user'].chomp
  ar_db_password        = slaughterhouse_database_credentials['ar_db_password'].chomp
  ar_db_name            = slaughterhouse_database_credentials['ar_db_name'].chomp
else
  # If no data bag is supplied, provide dummy values so that the service starts
  statement_db_host     = 'localhost'
  statement_db_user     = 'statement_db_user'
  statement_db_password = 'statement_db_password'
  statement_db_name     = 'stmt-db'
  ar_db_host            = 'localhost'
  ar_db_user            = 'ar_db_user'
  ar_db_password        = 'ar_db_password'
  ar_db_name            = 'art_relations'
end

setenv_params = Hash[
  'STATEMENT_DB_HOST' => statement_db_host,
  'STATEMENT_DB_USER' => statement_db_user,
  'STATEMENT_DB_PASSWORD' => statement_db_password,
  'STATEMENT_DB_NAME' => statement_db_name,
  'AR_DB_HOST' => ar_db_host,
  'AR_DB_USER' => ar_db_user,
  'AR_DB_PASSWORD' => ar_db_password,
  'AR_DB_NAME' => ar_db_name,
  'BACON_UPLOAD_PATH' => "#{slaughterhouse_root_directory}/slaughterhouse/dropbox/"
]

# The engine needs to source environment variables.
engine_env_file = "#{node['php']['deploy_home_dir']}/.env"
engine_env_file_content = ''

setenv_params.each do |key, value|
  engine_env_file_content += "export #{key}=#{value}\n"
end

file engine_env_file do
  owner node['php']['deploy_user']
  content engine_env_file_content
  mode '0600'
  sensitive true
end

slaughterhouse_log_directory = '/tmp/slaughterhouse'

directory slaughterhouse_log_directory do
  owner node['php']['deploy_user']
end

cron_users = [
  node['php']['deploy_user'],
  slaughterhouse_sftp_user,
]

ruby_block 'append_to_cron_dot_allow' do
  block do
    cron_allow = File.open('/etc/cron.allow', 'a+')
    cron_users.each do |user|
      unless cron_allow.each_line.any? { |line| line.include?(user) }
        cron_allow.write("#{user}\n")
      end
    end
    cron_allow.close()
  end
end

# Run Slaughterhouse engine. Escape backslashes so they escape % in crontab to ensure command substitution
cron 'slaughterhouse_engine_cron' do
  hour '*'
  minute '*'
  user node['php']['deploy_user']
  command "cd #{slaughterhouse_root_directory}/slaughterhouse; . #{engine_env_file} && "\
    "#{php_engine_binary} -f engine.php >> #{slaughterhouse_log_directory}/slaughterhouse_engine_$(date +\\%Y-\\%m-\\%d-\\%H:\\%M).log 2>&1"
end

# Simple cron to pull git changes. Recreated from previous configuration by request.
cron 'slaughterhouse_git_pull' do
  hour '*'
  minute '*/5'
  user node['php']['deploy_user']
  command "cd #{slaughterhouse_root_directory} && git pull && chgrp -R #{node['slaughterhouse']['application_directory_group']} ."
end

# Create ".aws" directory for service user
directory "#{node['php']['deploy_home_dir']}/.aws" do
  owner node['php']['deploy_user']
  mode '0755'
  recursive true
end

slaughterhouse_backup_aws_credentials = data_bag_item('secrets', node['slaughterhouse']['aws_credentials_data_bag_name'])
aws_access_key_id                     = slaughterhouse_backup_aws_credentials['aws_access_key_id'].chomp
aws_secret_access_key                 = slaughterhouse_backup_aws_credentials['aws_secret_access_key'].chomp

template "#{node['php']['deploy_home_dir']}/.aws/credentials" do
  source 'aws_credentials.erb'
  owner node['php']['deploy_user']
  mode '0640'
  variables(
    aws_access_key_id: aws_access_key_id,
    aws_secret_access_key: aws_secret_access_key
  )
  sensitive true
end

# Sync local logs to S3 on a schedule
slaughterhouse_log_backup_s3_path = node['slaughterhouse']['logfile_s3_bucket_path']
cron 'slaughterhouse_log_backup' do
  hour '*'
  minute '*/5'
  user node['php']['deploy_user']
  command "aws s3 sync #{slaughterhouse_log_directory} s3://#{slaughterhouse_log_backup_s3_path}/$(date +\\%Y-\\%m-\\%d)/ --sse"
end

# Remove local logs daily
cron 'slaughterhouse_log_cleanup' do
  hour '0'
  minute '0'
  user node['php']['deploy_user']
  command "find #{slaughterhouse_log_directory} -type f -exec rm -rf {} \\;"
end

# Empty the "trash" daily
cron 'slaughterhouse_trash_removal' do
  hour '1'
  minute '0'
  user slaughterhouse_sftp_user
  command "rm -rf #{home_directory}/dropbox/trash/*"
end

# This by default references a template with a matching name
apache_conf 'slaughterhouse' do
  enable true
end

# Explicitly disable the default site if it is active, as a failsafe.
execute 'a2dissite default' do
  only_if do
    File.symlink?(node['apache']['default_site_file_name'])
  end
  notifies :restart, 'service[apache2]'
end

# Vhost attributes are contained in roles
node['webapps'].each do |vhost, vhost_info|
  web_app vhost do
    template 'vhost.conf.erb'
    port vhost_info['port']
    server_admin vhost_info['server_admin']
    server_name vhost_info['server_name']
    if defined?(vhost_info['server_aliases'])
      server_aliases vhost_info['server_aliases']
    end
    docroot vhost_info['docroot']
    if defined?(vhost_info['docroot_rewrites'])
      docroot_rewrites vhost_info['docroot_rewrites']
    end
    if defined?(vhost_info['directory_options'])
      directory_options vhost_info['directory_options']
    end
    allow_override vhost_info['allow_override']
    setenv setenv_params if defined?(vhost_info['setenv'])
  end
end
