# syntax = docker/dockerfile:experimental
FROM ubuntu:22.04

ENV LANG C.UTF-8
ENV DEBIAN_FRONTEND noninteractive

ENV OPENBLAS_NUM_THREADS 1
ENV MKL_NUM_THREADS 1

# Install essential packages
RUN --mount=type=cache,target=/var/cache/apt apt-get update \
  && apt-get install --yes --no-install-suggests --no-install-recommends \
  # Essentials
  build-essential \
  git \
  mariadb-client \
  libmariadb-dev \
  pkg-config \
  pv \
  ntp \
  wget \
  curl \
  supervisor \
  file \
  # Dependencies for SSH access
  openssh-server \
  nano \
  vim \
  less \
  htop \
  iputils-ping \
  telnet \
  # Dependencies for adding Python PPA
  software-properties-common \
  gnupg \
  # weasyprint dependencies
  libpango-1.0-0 \
  libharfbuzz0b \
  libpangoft2-1.0-0 \
  libpangocairo-1.0-0 \
  # Chromium and dependencies
  chromium-browser \
  # wkhtmltopdf dependencies
  ca-certificates \
  fontconfig \
  libfreetype6 \
  libjpeg-turbo8 \
  libpng16-16 \
  libx11-6 \
  libxcb1 \
  libxext6 \
  libxrender1 \
  xfonts-75dpi \
  xfonts-base \
  # pycups dependencies
  gcc \
  libcups2-dev \
  # s3-attachment dependencies
  libmagic1 \
  && rm -rf /var/lib/apt/lists/* \
  `#stage-pre-essentials`

COPY --chown=root:root supervisord.conf /etc/supervisor/supervisord.conf

# Install Redis from PPA
RUN --mount=type=cache,target=/var/cache/apt curl -fsSL https://packages.redis.io/gpg | gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg \
  && echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb jammy main" | tee /etc/apt/sources.list.d/redis.list \
  && apt-get update \
  && apt-get install --yes --no-install-suggests --no-install-recommends \
  redis-server \
  && rm -rf /var/lib/apt/lists/* `#stage-pre-redis`

# Install Python from DeadSnakes PPA
ENV {{ pg.get_dependency_version("python", True) }}
RUN --mount=type=cache,target=/var/cache/apt add-apt-repository -y ppa:deadsnakes/ppa \
  && apt-get update \
  && apt-get install --yes --no-install-suggests --no-install-recommends \
  python${PYTHON_VERSION} \
  python${PYTHON_VERSION}-dev \
  python${PYTHON_VERSION}-venv \
  && rm -rf /var/lib/apt/lists/* \
  `#stage-pre-python`


# Install wkhtmltopdf
ENV {{ pg.get_dependency_version("wkhtmltopdf", True) }}
{% if pg.get_dependency_version("wkhtmltopdf") == '0.12.6' %}
RUN wget http://npm.jingrow.com:105/wkhtmltox_0.12.6.1-2.jammy_amd64.deb \
  && dpkg -i wkhtmltox_0.12.6.1-2.jammy_amd64.deb \
  && rm wkhtmltox_0.12.6.1-2.jammy_amd64.deb \
  `#stage-pre-wkhtmltopdf`
{% elif pg.get_dependency_version("wkhtmltopdf") == '0.12.5' %}
RUN wget http://npm.jingrow.com:105/wkhtmltox_0.12.5-1.jammy_amd64.deb \
  && dpkg -i wkhtmltox_0.12.5-1.jammy_amd64.deb \
  && rm wkhtmltox_0.12.5-1.jammy_amd64.deb \
  `#stage-pre-wkhtmltopdf`
{% elif pg.get_dependency_version("wkhtmltopdf") == '0.12.4' %}
RUN wget http://npm.jingrow.com:105/wkhtmltox-0.12.4_linux-generic-amd64.tar.xz \
  && tar -xvf wkhtmltox-0.12.4_linux-generic-amd64.tar.xz \
  && mv wkhtmltox/bin/wkhtmlto* /usr/local/bin/ \
  && rm -rf wkhtmltox-0.12.4_linux-generic-amd64.tar.xz wkhtmltox \
  `#stage-pre-wkhtmltopdf`
{% endif %}

{% if pg.is_code_server_enabled %}
RUN curl -fsSL https://code-server.dev/install.sh | sh `#stage-pre-code-server`
{% endif %}

# Install Fonts
RUN git clone --progress --depth 1 http://git.jingrow.com/jpub/fonts.git /tmp/fonts \
  && rm -rf /etc/fonts && mv /tmp/fonts/etc_fonts /etc/fonts \
  && rm -rf /usr/share/fonts && mv /tmp/fonts/usr_share_fonts /usr/share/fonts \
  && rm -rf /tmp/fonts \
  && fc-cache -fv \
  `#stage-pre-fonts`


# Set max_allowed_packet to 512 MB for mysqldump
RUN echo "[mysqldump]\nmax_allowed_packet              = 512M" > /etc/mysql/conf.d/mysqldump.cnf

# Add jingrow user
RUN useradd -ms /bin/bash jingrow

# Install Additional Packages
{% for p in pg.additional_packages %}

# Run before install scripts
{% if p.prerequisites %}
RUN --mount=type=cache,target=/var/cache/apt {{ p.prerequisites }} \
  `#stage-pre_before-{{ p.package }}`
{% endif %}

# Install non Ubuntu packages
{% if p.package_manager not in ["apt-get", "apt"] %}
RUN {{ p.package_manager }} install {{ p.package }} \
  `#stage-pre-{{ p.package }}`

# Install Ubuntu packages
{% else %}
RUN --mount=type=cache,target=/var/cache/apt apt-get update \
  && apt-get install --yes --no-install-suggests --no-install-recommends {{ p.package }} \
  && rm -rf /var/lib/apt/lists/* \
  `#stage-pre-{{ p.package }}`
{% endif %}

# Run after install scripts
{% if p.after_install %}
RUN  --mount=type=cache,target=/var/cache/apt {{ p.after_install }} \
  && rm -rf /var/lib/apt/lists/* \
  `#stage-pre_after-{{ p.package }}`
{% endif %}

{% endfor %}


# symlink mysqldump to mariadb-dump
RUN test -f /usr/bin/mariadb-dump || ln -s /usr/bin/mysqldump /usr/bin/mariadb-dump

WORKDIR /home/jingrow

# Install Node using NodeSource (as root to avoid GitHub access via nvm)
ENV {{ pg.get_dependency_version("node", True) }}
USER root
RUN NODE_MAJOR=$(echo ${NODE_VERSION} | cut -d. -f1) \
  && curl -fsSL https://deb.nodesource.com/setup_${NODE_MAJOR}.x | bash - \
  && apt-get update \
  && apt-get install --yes --no-install-suggests --no-install-recommends nodejs \
  && rm -rf /var/lib/apt/lists/* \
  `#stage-pre-node`

# Install Yarn globally
RUN npm install -g yarn `#stage-pre-yarn`

# Switch back to jingrow
USER jingrow


# Install Bench
# Set environment variables first
{% for v in pg.environment_variables %}
ENV {{v.key}} {{ v.value }}
{% endfor %}

# Install Bench
ENV PATH "$PATH:/home/jingrow/.local/bin"
RUN wget https://bootstrap.pypa.io/get-pip.py && python${PYTHON_VERSION} get-pip.py `#stage-pre-pip`
RUN python${PYTHON_VERSION} -m pip install --upgrade pip `#stage-pre-pip-upgrade`
RUN python${PYTHON_VERSION} -m pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple `#stage-pre-pip-mirror`
RUN python${PYTHON_VERSION} -m pip config set global.trusted-host pypi.tuna.tsinghua.edu.cn `#stage-pre-pip-trusted`
ENV {{ pg.get_dependency_version("bench", True) }}

# Now bench install command can use the environment variables
RUN --mount=type=cache,target=/home/jingrow/.cache,uid=1000,gid=1000 \
    python${PYTHON_VERSION} -m pip install --upgrade --resume-retries 5 --timeout 100 \
    git+http://${GIT_USERNAME:+$GIT_USERNAME:$GIT_ACCESS_TOKEN@}git.jingrow.com/jingrow/bench.git \
    `#stage-bench-bench`
RUN --mount=type=cache,target=/home/jingrow/.cache,uid=1000,gid=1000 python${PYTHON_VERSION} -m pip install Jinja2~=3.0.3
RUN --mount=type=cache,target=/home/jingrow/.cache,uid=1000,gid=1000 python${PYTHON_VERSION} -m pip install --upgrade setuptools

RUN git config --global advice.detachedHead false

ENV PYTHONUNBUFFERED 1

# For the sake of completing the step
RUN `#stage-bench-env`

# Install Jingrow app
ENV PIP_RETRIES=10
ENV PIP_TIMEOUT=300
ENV PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple
ENV PIP_TRUSTED_HOST=pypi.tuna.tsinghua.edu.cn
RUN --mount=type=cache,sharing=locked,target=/home/jingrow/.cache,uid=1000,gid=1000 --mount=type=bind,source=apps/jingrow,target=/home/jingrow/context/apps/jingrow bench init --python /usr/bin/python${PYTHON_VERSION} --no-backups --jingrow-path file:///home/jingrow/context/apps/jingrow jingrow-bench `#stage-apps-jingrow`
WORKDIR /home/jingrow/jingrow-bench

RUN --mount=type=cache,target=/home/jingrow/.cache,uid=1000,gid=1000 /home/jingrow/jingrow-bench/env/bin/pip install pycups==2.0.1

# Install Redisearch 2.0 from precompiled binaries
COPY --chown=jingrow:jingrow redis /home/jingrow/jingrow-bench/redis
COPY --chown=jingrow:jingrow .vimrc /home/jingrow/.vimrc
COPY --chown=jingrow:jingrow common_site_config.json /home/jingrow/jingrow-bench/sites/common_site_config.json

# Install other apps
{% for app in pg.apps %}
{% if app.app != "jingrow" %}

RUN --mount=type=cache,sharing=locked,target=/home/jingrow/.cache,uid=1000,gid=1000 \
  --mount=type=bind,source=apps/{{ app.app }},target=/home/jingrow/context/apps/{{ app.app }} \
  bench get-app file:///home/jingrow/context/apps/{{ app.app }} \
    {% if app.use_cached %}
    # Bench get-app flags to use get-app cache
    --cache-key {{ app.hash }} {% if pg.compress_app_cache %}--compress-artifacts{% endif %} \
    {% endif %}
  `#stage-apps-{{ app.app }}`

{% endif %}
{% endfor %}

# Pull app updates from mounted repository
{% for app in pg.apps %}
{% if app.pullable_release %}
RUN --mount=type=bind,source=app_updates/{{ app.app }},target=/home/jingrow/context/app_updates/{{ app.app }} \
  cd /home/jingrow/jingrow-bench/apps/{{ app.app }} \
  && git reset --hard \
  && git remote add -f app_update /home/jingrow/context/app_updates/{{ app.app }} \
  && git fetch --depth 1 app_update {{ app.pullable_hash }} \
  && git checkout {{ app.pullable_hash }} \
  && git remote remove app_update \
  `#stage-pull-{{ app.app }}`
{% endif %}
{% endfor %}


COPY --chown=jingrow:jingrow config /home/jingrow/jingrow-bench/config
COPY --chown=jingrow:jingrow apps.txt /home/jingrow/jingrow-bench/sites/apps.txt

# Create custom mounts
{% for m in pg.container_mounts %}
RUN mkdir -p {{ m.destination }} && \
  chown -R jingrow:jingrow {{ m.destination }} \
  `#stage-mounts-create`
{% endfor %}

ENV JINGROW_HARD_LINK_ASSETS True
ENV HISTTIMEFORMAT "%Y-%m-%d %T "

EXPOSE 8000 9000 2200 8088
CMD ["supervisord"]
