#!/usr/bin/env bash

export DEBIAN_FRONTEND=noninteractive

apt -qq update
apt -y -qq install \
	git nginx \
	php7.4 php7.4-fpm php7.4-mysql php7.4-gd php7.4-curl php7.4-apcu php7.4-cli php7.4-json php7.4-mbstring php7.4-zip php7.4-xdebug \
	ssh mariadb-server wget vim less zip cron lsof sudo supervisor python3-pygments mariadb-client gcc g++ nodejs npm

# Add users
echo "git:x:2000:2000:user for phorge ssh:/srv/phorge:/bin/bash" >> /etc/passwd
echo "phorge-daemon:x:2001:2000:user for phorge daemons:/srv/phorge:/bin/bash" >> /etc/passwd
echo "wwwgrp-phorge:!:2000:nginx" >> /etc/group

usermod -p NP git

# Add repo directory
mkdir -p /var/repo/
chown phorge-daemon:2000 /var/repo/
mkdir -p /var/tmp/phd/pid
chmod 0777 /var/tmp/phd/pid

# Add git to sudoers
echo "git ALL=(phorge-daemon) SETENV: NOPASSWD: /usr/bin/git-upload-pack, /usr/bin/git-receive-pack, /usr/bin/git, /usr/lib/git-core/git-http-backend" > /etc/sudoers.d/git

echo 'export PATH="/srv/phorge/arcanist/bin:$PATH"' >> /root/.bashrc
echo 'export PATH="/srv/phorge/phorge/bin:$PATH"' >> /root/.bashrc

chown git:wwwgrp-phorge /srv/phorge
sudo su git
cd /srv/phorge
git clone https://we.phorge.it/source/phorge.git
git clone https://we.phorge.it/source/arcanist.git
sudo su -
cd /
mkdir -p /var/tmp/phd/log
chown phorge-daemon:2000 /var/tmp/phd/log

cat << "EOF" > /etc/nginx/nginx.conf
worker_processes  1;
#daemon off;
pid        /run/nginx.pid;

events {
	worker_connections  1024;
	use epoll;
}

http {
	include       mime.types;
	default_type  application/octet-stream;
	sendfile        on;
	keepalive_timeout  65;
	gzip  on;
	client_max_body_size  200M;
	client_body_buffer_size 200M;

	server {
		listen       *:80;

		access_log /var/log/nginx/access.log;
		error_log /var/log/nginx/access.log;

		root /srv/phorge/phorge/webroot;
		try_files $uri $uri/ /index.php;

		location / {
			index index.php;

			if ( !-f $request_filename )
			{
				rewrite ^/(.*)$ /index.php?__path__=/$1 last;
				break;
			}
		}

		location /index.php {
			include /etc/nginx/fastcgi.conf;
			fastcgi_param PATH "/usr/local/bin:/usr/bin:/sbin:/usr/sbin:/bin:/usr/games";
			fastcgi_pass unix:/tmp/php-fpm-phorge.sock;
		}
	}
}
EOF

cat << "EOF" > /etc/nginx/fastcgi.conf
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

fastcgi_param  HTTPS              $https;

fastcgi_read_timeout 6000;
EOF

cat << "EOF" > /etc/php/7.4/fpm/php-fpm.conf
[global]
pid = /run/php-fpm.pid
error_log = /tmp/phorge.log
;daemonize = nomkdir

[phorge]
user = git
group = wwwgrp-phorge
listen = /tmp/php-fpm-phorge.sock
listen.owner = git
listen.group = wwwgrp-phorge
listen.mode = 0666
pm = dynamic
pm.max_children = 4
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 4
catch_workers_output = yes
php_admin_value[error_log] = /tmp/phorge.php.log
EOF

cat << "EOF" > /etc/php/7.4/fpm/php.ini
[PHP]
engine = On
short_open_tag = Off
asp_tags = Off
precision = 14
y2k_compliance = On
output_buffering = 4096
zlib.output_compression = Off
unserialize_callback_func =
serialize_precision = 17
allow_call_time_pass_reference = Off
safe_mode = Off
safe_mode_gid = Off
safe_mode_include_dir =
safe_mode_exec_dir =
safe_mode_allowed_env_vars = PHP_
safe_mode_protected_env_vars = LD_LIBRARY_PATH
disable_functions =
disable_classes =
zend.enable_gc = On
expose_php = On
max_input_time = 60
memory_limit = 4G
error_reporting = E_ALL & ~E_DEPRECATED
display_errors = On
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
track_errors = Off
error_log = /tmp/php_errors.log
variables_order = "GPCS"
request_order = "GP"
register_globals = Off
register_long_arrays = Off
auto_globals_jit = On
post_max_size = 4G
magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
include_path = ".:/usr/share/php7:/usr/share/php7/PEAR:/srv/phorge/PHPExcel/Classes"
doc_root =
user_dir =
enable_dl = Off
file_uploads = On
upload_max_filesize = 4G
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60
opcache.validate_timestamps = On
opcache.revalidate_freq = 0
xdebug.remote_enable=1
xdebug.remote_autostart=1
xdebug.remote_port="9001"
xdebug.profiler_enable=0
xdebug.profiler_output_dir="/tmp"
xdebug.max_nesting_level=1000
xdebug.idekey = "PHPSTORM"
[Date]
date.timezone = 'UTC'
[filter]
[iconv]
[intl]
[sqlite]
[sqlite3]
[Pcre]
[Pdo]
[Pdo_mysql]
pdo_mysql.cache_size = 2000
pdo_mysql.default_socket=
[Phar]
[Syslog]
define_syslog_variables  = Off
[mail function]
SMTP = localhost
smtp_port = 25
mail.add_x_header = On
[SQL]
sql.safe_mode = Off
[ODBC]
odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1
[Interbase]
ibase.allow_persistent = 1
ibase.max_persistent = -1
ibase.max_links = -1
ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
ibase.dateformat = "%Y-%m-%d"
ibase.timeformat = "%H:%M:%S"
[MySQL]
mysql.allow_local_infile = On
mysql.allow_persistent = Off
mysql.cache_size = 2000
mysql.max_persistent = -1
mysql.max_links = -1
mysql.default_port =
mysql.default_socket =
mysql.default_host =
mysql.default_user =
mysql.default_password =
mysql.connect_timeout = 3
mysql.trace_mode = Off
[MySQLi]
mysqli.max_persistent = -1
mysqli.allow_persistent = Off
mysqli.max_links = -1
mysqli.cache_size = 2000
mysqli.default_port = 3306
mysqli.default_socket =
mysqli.default_host =
mysqli.default_user =
mysqli.default_pw =
mysqli.reconnect = Off
[mysqlnd]
mysqlnd.collect_statistics = On
mysqlnd.collect_memory_statistics = Off
[OCI8]
[PostgreSQL]
pgsql.allow_persistent = On
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice = 0
[Sybase-CT]
sybct.allow_persistent = On
sybct.max_persistent = -1
sybct.max_links = -1
sybct.min_server_severity = 10
sybct.min_client_severity = 10
[bcmath]
bcmath.scale = 0
[browscap]
[Session]
session.save_handler = files
session.save_path = "/var/lib/php5"
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.bug_compat_42 = Off
session.bug_compat_warn = Off
session.referer_check =
session.entropy_length = 32
session.entropy_file = /dev/urandom
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = sha256
session.hash_bits_per_character = 5
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"
[MSSQL]
mssql.allow_persistent = On
mssql.max_persistent = -1
mssql.max_links = -1
mssql.min_error_severity = 10
mssql.min_message_severity = 10
mssql.compatability_mode = Off
mssql.secure_connection = Off
[Assertion]
[COM]
[mbstring]
[gd]
[exif]
[Tidy]
tidy.clean_output = Off
[soap]
soap.wsdl_cache_enabled=1
soap.wsdl_cache_dir="/tmp"
soap.wsdl_cache_ttl=86400
soap.wsdl_cache_limit = 5
[sysvshm]
[ldap]
ldap.max_links = -1
[mcrypt]
[dba]
[xsl]
EOF

mkdir -p /install_scripts

cat << "EOF" > /install_scripts/aphlict.phorge.json
[{
	"type": "client",
	"host": "phorge.localhost",
	"port": 22280,
	"protocol": "http"
},
{
	"type": "admin",
	"host": "127.0.0.1",
	"port": 22281,
	"protocol": "http"
}]
EOF

mkdir -p /var/log/supervisor
mkdir -p /etc/supervisor/conf.d/

cat << "EOF" > /etc/supervisor/supervisord.conf
; supervisor config file

[unix_http_server]
file=/var/run/supervisor.sock   ; (the path to the socket file)
chmod=0700                       ; sockef file mode (default 0700)

[supervisord]
nodaemon=true
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor            ; ('AUTO' child log dir, default $TEMP)

; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL  for a unix socket

; The [include] section can just contain the "files" setting.  This
; setting can list multiple files (separated by whitespace or
; newlines).  It can also contain wildcards.  The filenames are
; interpreted as relative to this file.  Included files *cannot*
; include files themselves.

[include]
files = /etc/supervisor/conf.d/*.conf
EOF

cat << "EOF" > /etc/supervisor/conf.d/aphlict.sv.conf
[program:aphlict]
command=/srv/phorge/phorge/bin/aphlict debug --config /srv/phorge/phorge/conf/aphlict/aphlict.default.json
user=phorge-daemon
EOF

#cat << "EOF" > /etc/supervisor/conf.d/nginx.sv.conf
#[program:nginx]
#command=nginx
#EOF

cat << "EOF" > /etc/supervisor/conf.d/phorge-phd.sv.conf
[program:PhabricatorRepositoryPullLocalDaemon]
user=phorge-daemon
command=/srv/phorge/phorge/bin/phd debug PhabricatorRepositoryPullLocalDaemon
stdout_logfile=/var/log/supervisor/PhabricatorRepositoryPullLocalDaemon.log
stderr_logfile=/var/log/supervisor/PhabricatorRepositoryPullLocalDaemon_err.log

[program:PhabricatorTaskmasterDaemon1]
user=phorge-daemon
command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon
stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon1.log
stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon1_err.log

[program:PhabricatorTaskmasterDaemon2]
user=phorge-daemon
command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon
stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon2.log
stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon2_err.log

[program:PhabricatorTaskmasterDaemon3]
user=phorge-daemon
command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon
stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon3.log
stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon3_err.log

[program:PhabricatorTaskmasterDaemon4]
user=phorge-daemon
command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon
stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon4.log
stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon4_err.log

[group:phd]
programs=PhabricatorRepositoryPullLocalDaemon,PhabricatorTaskmasterDaemon1,PhabricatorTaskmasterDaemon2,PhabricatorTaskmasterDaemon3,PhabricatorTaskmasterDaemon4
EOF

cat << "EOF" > /etc/supervisor/conf.d/phorge-sshd.sv.conf
[program:phorge-sshd]
command=/usr/sbin/sshd -D -f /etc/phorge-ssh/sshd_config.phorge
EOF

#cat << "EOF" > /etc/supervisor/conf.d/php7-fpm.sv.conf
#[program:php7.4-fpm]
#command=php-fpm7.4 -F
#EOF

mkdir -p /etc/phorge-ssh
mkdir -p /var/run/sshd/
chmod 0755 /var/run/sshd

cat << "EOF" > /etc/phorge-ssh/sshd_config.phorge
# NOTE: You must have OpenSSHD 6.2 or newer; support for AuthorizedKeysCommand
# was added in this version.

# NOTE: Edit these to the correct values for your setup.

AuthorizedKeysCommand /etc/phorge-ssh/phorge-ssh-hook.sh
AuthorizedKeysCommandUser git
AllowUsers git

# You may need to tweak these options, but mostly they just turn off everything
# dangerous.

Port 2222
Protocol 2
PermitRootLogin no
AllowAgentForwarding no
AllowTcpForwarding no
PrintMotd no
PrintLastLog no
PasswordAuthentication no
AuthorizedKeysFile none

PidFile /run/sshd-phorge.pid
EOF

cat << "EOF" > /etc/phorge-ssh/phorge-ssh-hook.sh
#!/bin/sh

# NOTE: Replace this with the username that you expect users to connect with.
VCSUSER="git"

ROOT="/srv/phorge/phorge"

if [ "$1" != "$VCSUSER" ];
then
  exit 1
fi

exec "$ROOT/bin/ssh-auth" $@
EOF

chown root:root /etc/phorge-ssh/*

mkdir -p /user-config
touch /user-config/.exists

mysql -e "CREATE USER 'phorge-dev'@'localhost' IDENTIFIED BY 'phorge-dev';"
mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'phorge-dev'@'localhost' IDENTIFIED BY 'phorge-dev';"
mysql -e "FLUSH PRIVILEGES;"

/srv/phorge/phorge/bin/config set mysql.user 'phorge-dev'
/srv/phorge/phorge/bin/config set mysql.pass 'phorge-dev'

/srv/phorge/phorge/bin/storage upgrade --force

service nginx restart
service php7.4-fpm restart