name: Windows.

on:
  push:
    paths-ignore:
      - 'docs/**'
      - '**.md'
      - '!docs/building-msvc.md'
      - 'changelog.txt'
      - 'LEGAL'
      - 'LICENSE'
      - '.github/**'
      - '!.github/workflows/win.yml'
      - 'lib/xdg/**'
      - 'snap/**'
      - 'Telegram/build/**'
      - 'Telegram/Patches/**'
      - '!Telegram/Patches/build_ffmpeg_win.sh'
      - 'Telegram/Resources/uwp/**'
      - 'Telegram/SourceFiles/platform/linux/**'
      - 'Telegram/SourceFiles/platform/mac/**'
      - 'Telegram/Telegram/**'
      - 'Telegram/configure.sh'
      - 'Telegram/Telegram.plist'
  pull_request:
    paths-ignore:
      - 'docs/**'
      - '**.md'
      - '!docs/building-msvc.md'
      - 'changelog.txt'
      - 'LEGAL'
      - 'LICENSE'
      - '.github/**'
      - '!.github/workflows/win.yml'
      - 'lib/xdg/**'
      - 'snap/**'
      - 'Telegram/build/**'
      - 'Telegram/Patches/**'
      - '!Telegram/Patches/build_ffmpeg_win.sh'
      - 'Telegram/Resources/uwp/**'
      - 'Telegram/SourceFiles/platform/linux/**'
      - 'Telegram/SourceFiles/platform/mac/**'
      - '!Telegram/Patches/breakpad.diff'
      - 'Telegram/Telegram/**'
      - 'Telegram/configure.sh'
      - 'Telegram/Telegram.plist'

jobs:

  windows:
    name: Windows
    runs-on: windows-latest

    strategy:
      matrix:
        defines:
          - ""
    env:
      SDK: "10.0.18362.0"
      VC: "call vcvars32.bat && cd Libraries"
      GIT: "https://github.com"
      QT: "5_15_2"
      QT_VER: "5.15.2"
      OPENSSL_VER: "1_1_1"
      UPLOAD_ARTIFACT: "false"
      ONLY_CACHE: "false"
      MANUAL_CACHING: "2"
      DOC_PATH: "docs/building-msvc.md"
      AUTO_CACHING: "1"

    defaults:
      run:
        shell: cmd

    steps:
      - name: Get repository name.
        shell: bash
        run: echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV

      - name: Set up environment paths.
        shell: bash
        run: |
          echo "C:\\Strawberry\\perl\\bin\\" >> $GITHUB_PATH
          echo "C:\\Program Files\\NASM\\" >> $GITHUB_PATH
          echo "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\VC\\Auxiliary\\Build\\" >> $GITHUB_PATH

          mkdir Libraries && cd Libraries
          echo "Convert unix path to win path."
          p=`pwd | sed 's#^/[d]#d:#g' |sed 's#/#\\\\#g'`
          echo "LibrariesPath=$p" >> $GITHUB_ENV

      - name: Save msbuild version.
        run: |
          call vcvars32.bat
          msbuild -version > CACHE_KEY.txt

      - name: Clone.
        uses: actions/checkout@v2
        with:
          submodules: recursive
          path: ${{ env.REPO_NAME }}

      - name: Generate cache key.
        shell: bash
        run: |
          curl -o $LibrariesPath/tg_owt-version.json https://api.github.com/repos/desktop-app/tg_owt/git/refs/heads/master
          echo $MANUAL_CACHING >> CACHE_KEY.txt
          if [ "$AUTO_CACHING" == "1" ]; then
            thisFile=$REPO_NAME/.github/workflows/win.yml
            echo `md5sum $thisFile | awk '{ print $1 }'` >> CACHE_KEY.txt
          fi
          echo "CACHE_KEY=`md5sum CACHE_KEY.txt | awk '{ print $1 }'`" >> $GITHUB_ENV

      - name: Choco installs.
        run: choco install --no-progress -y nasm yasm jom ninja

      - name: Patches.
        shell: bash
        run: |
          echo "Find necessary commit from doc."
          checkoutCommit=$(grep -A 1 "cd patches" $REPO_NAME/$DOC_PATH | sed -n 2p)
          cd $LibrariesPath
          git clone $GIT/desktop-app/patches.git
          cd Patches
          eval $checkoutCommit

      - name: Find any version of Python 2.
        shell: bash
        run: |
          echo "Find any version of Python 2."
          p=`ls /c/hostedtoolcache/windows/python | grep "^2" | tail -1`
          if [ -z "$p" ]; then
            echo "Python 2 is not found."
            exit 1
          fi
          echo "PY2=C:\\hostedtoolcache\\windows\\Python\\$p\\x64" >> $GITHUB_ENV
          echo "Found $p."

      - name: LZMA.
        run: |
          %VC%

          git clone %GIT%/telegramdesktop/lzma.git
          cd lzma
          cd C\Util\LzmaLib
          msbuild -m LzmaLib.sln /property:Configuration=Debug

      - name: OpenSSL cache.
        id: cache-openssl
        uses: actions/cache@v2
        with:
          path: ${{ env.LibrariesPath }}/openssl_${{ env.OPENSSL_VER }}
          key: ${{ runner.OS }}-${{ env.CACHE_KEY }}-${{ env.OPENSSL_VER }}
      - name: OpenSSL.
        if: steps.cache-openssl.outputs.cache-hit != 'true'
        run: |
          %VC%

          git clone %GIT%/openssl/openssl.git openssl_%OPENSSL_VER%
          cd openssl_%OPENSSL_VER%
          git checkout OpenSSL_%OPENSSL_VER%-stable
          perl Configure no-shared no-tests debug-VC-WIN32
          nmake
          mkdir out32.dbg
          move libcrypto.lib out32.dbg
          move libssl.lib out32.dbg
          move ossl_static.pdb out32.dbg\ossl_static
          nmake clean
          move out32.dbg\ossl_static out32.dbg\ossl_static.pdb
          perl Configure no-shared no-tests VC-WIN32
          nmake
          mkdir out32
          move libcrypto.lib out32
          move libssl.lib out32
          move ossl_static.pdb out32

          rmdir /S /Q test
          rmdir /S /Q .git

      - name: Zlib.
        run: |
          %VC%

          git clone %GIT%/telegramdesktop/zlib.git
          cd zlib
          git checkout tdesktop
          cd contrib\vstudio\vc14
          msbuild -m zlibstat.vcxproj /property:Configuration=Debug

      - name: MozJPEG.
        shell: cmd
        run: |
          %VC%

          git clone -b v4.0.1-rc2 %GIT%/mozilla/mozjpeg.git
          cd mozjpeg
          cmake . ^
          -G "Visual Studio 16 2019" ^
          -A Win32 ^
          -DWITH_JPEG8=ON ^
          -DPNG_SUPPORTED=OFF
          cmake --build . --config Debug

      - name: OpenAL Soft cache.
        id: cache-openal
        uses: actions/cache@v2
        with:
          path: ${{ env.LibrariesPath }}/openal-soft
          key: ${{ runner.OS }}-openal-soft-${{ env.CACHE_KEY }}
      - name: OpenAL Soft.
        if: steps.cache-openal.outputs.cache-hit != 'true'
        run: |
          %VC%

          git clone -b openal-soft-1.21.0 --depth=1 %GIT%/kcat/openal-soft.git
          cd openal-soft\build
          cmake .. ^
          -G "Visual Studio 16 2019" ^
          -A Win32 ^
          -D LIBTYPE:STRING=STATIC ^
          -D FORCE_STATIC_VCRT=ON ^
          -D ALSOFT_BACKEND_DSOUND=OFF

          msbuild -m OpenAL.vcxproj /property:Configuration=Debug

      - name: Breakpad cache.
        id: cache-breakpad
        uses: actions/cache@v2
        with:
          path: ${{ env.LibrariesPath }}/breakpad
          key: ${{ runner.OS }}-breakpad-${{ env.CACHE_KEY }}-${{ hashFiles('**/breakpad.diff') }}
      - name: Breakpad.
        env:
          GYP_MSVS_OVERRIDE_PATH: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\'
          GYP_MSVS_VERSION: 2019
        if: steps.cache-breakpad.outputs.cache-hit != 'true'
        run: |
          cd %LibrariesPath%

          git clone %GIT%/telegramdesktop/gyp.git
          cd gyp
          SET PATH=%PY2%;%cd%;%PATH%
          git checkout tdesktop

          cd %LibrariesPath%

          git clone %GIT%/google/breakpad
          cd breakpad
          git checkout a1dbcdcb43
          git apply ../patches/breakpad.diff
          cd src
          git clone %GIT%/google/googletest testing
          cd client\windows
          call gyp --no-circular-check breakpad_client.gyp --format=ninja
          cd ..\..
          ninja -C out/Debug common crash_generation_client exception_handler
          ninja -C out/Release common crash_generation_client exception_handler
          cd tools\windows\dump_syms
          call gyp dump_syms.gyp

          call vcvars32.bat
          msbuild -m dump_syms.vcxproj /property:Configuration=Release

      - name: Opus cache.
        id: cache-opus
        uses: actions/cache@v2
        with:
          path: ${{ env.LibrariesPath }}/opus
          key: ${{ runner.OS }}-opus-${{ env.CACHE_KEY }}
      - name: Opus.
        if: steps.cache-opus.outputs.cache-hit != 'true'
        run: |
          %VC%

          git clone %GIT%/telegramdesktop/opus.git
          cd opus
          git checkout tdesktop
          cd win32\VS2015
          msbuild -m opus.sln /property:Configuration=Debug /property:Platform="Win32"
          msbuild -m opus.sln /property:Configuration=Release /property:Platform="Win32"

      - name: FFmpeg cache.
        id: cache-ffmpeg
        uses: actions/cache@v2
        with:
          path: ${{ env.LibrariesPath }}/ffmpeg
          key: ${{ runner.OS }}-ffmpeg-${{ env.CACHE_KEY }}-2-${{ hashFiles('**/build_ffmpeg_win.sh') }}
      - name: FFmpeg.
        if: steps.cache-ffmpeg.outputs.cache-hit != 'true'
        run: |
          %VC%
          choco install --no-progress -y msys2

          git clone %GIT%/FFmpeg/FFmpeg.git ffmpeg
          cd ffmpeg
          git checkout release/4.2
          set CHERE_INVOKING=enabled_from_arguments
          set MSYS2_PATH_TYPE=inherit
          call c:\tools\msys64\usr\bin\bash --login ../patches/build_ffmpeg_win.sh

          rmdir /S /Q .git

      - name: Qt 5.15.2 cache.
        id: cache-qt
        uses: actions/cache@v2
        with:
          path: ${{ env.LibrariesPath }}/Qt-${{ env.QT_VER }}
          key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qtbase_5_15_2/*') }}
      - name: Configure Qt 5.15.2.
        if: steps.cache-qt.outputs.cache-hit != 'true'
        run: |
          %VC%

          git clone git://code.qt.io/qt/qt5.git qt_%QT%
          cd qt_%QT%
          perl init-repository --module-subset=qtbase,qtimageformats
          git checkout v%QT_VER%
          git submodule update qtbase
          git submodule update qtimageformats
          cd qtbase
          for /r %%i in (..\..\patches\qtbase_%QT%\*) do git apply %%i
          cd ..

          SET SSL=%LibrariesPath%\openssl_%OPENSSL_VER%
          SET LIBS=libcrypto.lib Ws2_32.lib Gdi32.lib Advapi32.lib Crypt32.lib User32.lib

          configure ^
          -prefix "%LibrariesPath%\Qt-%QT_VER%" ^
          -debug ^
          -force-debug-info ^
          -opensource ^
          -confirm-license ^
          -static ^
          -static-runtime -I "%SSL%\include" ^
          -no-opengl ^
          -openssl-linked ^
          OPENSSL_LIBS_DEBUG="%SSL%\out32.dbg\libssl.lib %SSL%\out32.dbg\%LIBS%" ^
          OPENSSL_LIBS_RELEASE="%SSL%\out32\libssl.lib %SSL%\out32\%LIBS%" ^
          -mp ^
          -nomake examples ^
          -nomake tests ^
          -platform win32-msvc ^
          -I "%LibrariesPath%\mozjpeg" ^
          LIBJPEG_LIBS_DEBUG="%LibrariesPath%\mozjpeg\Debug\jpeg-static.lib" ^
          LIBJPEG_LIBS_RELEASE="%LibrariesPath%\mozjpeg\Release\jpeg-static.lib"
      - name: Qt 5.15.2 build.
        if: steps.cache-qt.outputs.cache-hit != 'true'
        run: |
          %VC%
          cd qt_%QT%

          jom -j%NUMBER_OF_PROCESSORS%
          jom -j%NUMBER_OF_PROCESSORS% install

          cd ..
          rmdir /S /Q qt_%QT%

      - name: WebRTC cache.
        id: cache-webrtc
        uses: actions/cache@v2
        with:
          path: ${{ env.LibrariesPath }}/tg_owt
          key: ${{ runner.OS }}-webrtc-${{ env.CACHE_KEY }}-${{ hashFiles('**/tg_owt-version.json') }}
      - name: WebRTC.
        if: steps.cache-webrtc.outputs.cache-hit != 'true'
        run: |
          %VC%

          git clone --recursive %GIT%/desktop-app/tg_owt.git
          mkdir tg_owt\out\Debug
          cd tg_owt\out\Debug
          cmake -G Ninja ^
          -DCMAKE_BUILD_TYPE=Debug ^
          -DTG_OWT_SPECIAL_TARGET=win ^
          -DTG_OWT_LIBJPEG_INCLUDE_PATH=%cd%/../../../mozjpeg ^
          -DTG_OWT_OPENSSL_INCLUDE_PATH=%cd%/../../../openssl_%OPENSSL_VER%/include ^
          -DTG_OWT_OPUS_INCLUDE_PATH=%cd%/../../../opus/include ^
          -DTG_OWT_FFMPEG_INCLUDE_PATH=%cd%/../../../ffmpeg ^
          ../..

          ninja

          :: Cleanup.
          cd %LibrariesPath%\tg_owt
          move out\Debug\tg_owt.lib tg_owt.lib
          rmdir /S /Q out
          mkdir out\Debug
          move tg_owt.lib out\Debug\tg_owt.lib

      - name: Read defines.
        shell: bash
        run: |
          DEFINE=""
          if [ -n "${{ matrix.defines }}" ]; then
            DEFINE="-D ${{ matrix.defines }}=ON"
            echo Define from matrix: $DEFINE
            echo "ARTIFACT_NAME=Telegram_${{ matrix.defines }}" >> $GITHUB_ENV
          else
            echo "ARTIFACT_NAME=Telegram" >> $GITHUB_ENV
          fi
          echo "TDESKTOP_BUILD_DEFINE=$DEFINE" >> $GITHUB_ENV

      - name: Telegram Desktop build.
        if: env.ONLY_CACHE == 'false'
        run: |
          cd %REPO_NAME%\Telegram

          call configure.bat ^
          -D TDESKTOP_API_TEST=ON ^
          -D DESKTOP_APP_USE_PACKAGED=OFF ^
          -D DESKTOP_APP_DISABLE_CRASH_REPORTS=OFF ^
          -D DESKTOP_APP_NO_PDB=ON ^
          %TDESKTOP_BUILD_DEFINE% ^
          -DCMAKE_SYSTEM_VERSION=%SDK%

          call vcvars32.bat
          cd ..\out
          msbuild -m Telegram.sln /nologo /p:Configuration=Debug,Platform=Win32

      - name: Move artifact.
        if: env.UPLOAD_ARTIFACT == 'true'
        run: |
          cd %REPO_NAME%\out\Debug
          mkdir artifact
          move Telegram.exe artifact/
      - uses: actions/upload-artifact@master
        name: Upload artifact.
        if: env.UPLOAD_ARTIFACT == 'true'
        with:
          name: ${{ env.ARTIFACT_NAME }}
          path: ${{ env.REPO_NAME }}\out\Debug\artifact\
