references:
  - &defaults
    docker:
      - image: circleci/ruby:latest

  - &workspace_root
    ~/

  - &capture_coverage_data
    run:
      name: Capturing coverage data
      command: |
        set -e
        sudo apt-get install -qq python-pip
        sudo pip install cpp-coveralls

        # further, these files will be saved in cache and used in "send-coverage" step
        # see "merge_and_upload_coverage_data" and "save_cache" records
        coveralls --dump coverage.${CIRCLE_JOB}.dump

  - &merge_and_upload_coverage_data
    run:
      name: Merging and uploading coverage data
      command: |
        set -e
        if [ -f ~/project/coverage.rspamd-test.dump ] && [ -f ~/project/coverage.functional.dump ]; then
            sudo apt-get install -qq python-pip python-dev
            sudo pip install --upgrade setuptools
            sudo pip install --upgrade pyOpenSSL
            sudo pip install cpp-coveralls requests cryptography

            cd ~/project
            if [ ! -z $COVERALLS_REPO_TOKEN ]; then
              # Merge Lua coverage (collected into lua_coverage_report.json) and with C-coverage
              # (in coverage.rspamd-test.dump, coverage.functional.dump, see &capture_coverage_data)
              # and finally upload it into coveralls.io
              test/tools/merge_coveralls.py --input coverage.functional.dump coverage.rspamd-test.dump lua_coverage_report.json unit_test_lua.json --output out.josn --token=${COVERALLS_REPO_TOKEN}
            fi
        fi

version: 2
jobs:
  build:
    <<: *defaults
    steps:
      - checkout

      - run: sudo apt-get update -qq || true
      - run: sudo apt-get install -qq cmake libevent-dev libglib2.0-dev libicu-dev libluajit-5.1-dev libmagic-dev libsqlite3-dev libssl-dev ragel libunwind-dev libunwind8

      - run: mkdir ../build ; mkdir ../install ; cd ../build
      # this weird peice is needed to properly collect coverage
      # rspamd works under "nobody" user and will not be able to dump
      # the coverage if directories have restrictive permissions
      - run: umask 0000
      - run: cmake ../project -DDBDIR=/nana -DENABLE_COVERAGE=ON -DENABLE_LIBUNWIND=ON -DCMAKE_INSTALL_PREFIX=../install

      - run: make install -j`nproc`

      - persist_to_workspace:
          root: *workspace_root
          paths:
            - project
            - build
            - install

  rspamd-test:
    <<: *defaults
    steps:
      - attach_workspace:
          at: *workspace_root

      - run: sudo apt-get update -qq || true
      - run: sudo apt-get install -qq cmake libevent-dev libglib2.0-dev libicu-dev libluajit-5.1-dev libmagic-dev libsqlite3-dev libssl-dev ragel libunwind-dev libunwind8 luarocks
      - run: sudo luarocks install luacheck
      - run: sudo luarocks install luacov
      - run: sudo luarocks install luacov-coveralls

      - run: cd ../build
      - run: make rspamd-test -j`nproc`
      - run: set +e; test/rspamd-test -p /rspamd/lua; echo "export RETURN_CODE=$?" >> $BASH_ENV
      - run: luacov-coveralls -o unit_test_lua.json --dryrun

      - *capture_coverage_data

      # Share coverage data between jobs
      - save_cache:
          key: coverage-rspamd-test-{{ .Environment.CIRCLE_WORKFLOW_ID }}
          paths:
            - coverage.rspamd-test.dump
            - unit_test_lua.json

      - run: (exit $RETURN_CODE)

  functional:
    <<: *defaults
    steps:
      - attach_workspace:
          at: *workspace_root

      - run: echo 'deb http://repo.yandex.ru/clickhouse/deb/stable/ main/' | sudo tee /etc/apt/sources.list.d/clickhouse.list
      - run: sudo apt-key adv --keyserver keyserver.ubuntu.com --recv E0C56BD4    # optional, clickhouse key

      - run: sudo apt-get update -qq || true
      - run: sudo apt-get install -qq libluajit-5.1-dev libpcre3-dev luarocks opendkim-tools python-pip redis-server libunwind8 libglib2.0-dev libicu-dev libevent-dev python-dev
      - run: sudo apt-get install clickhouse-server

      - run: sudo pip install demjson psutil robotframework requests http
      - run: sudo luarocks install luacheck
      - run: sudo luarocks install luacov
      - run: sudo luarocks install luacov-coveralls

      - run: cd ../build
      # see coverage notice in "build" stage
      - run: set +e; RSPAMD_INSTALLROOT=../install sudo -E bash -c "umask 0000; robot -x xunit.xml --exclude isbroken ../project/test/functional/cases"; echo "export RETURN_CODE=$?" >> $BASH_ENV
      # luacov-coveralls reads luacov.stats.out generated by functional tests
      # (see collect_lua_coverage() in test/functional/lib/rspamd.py)
      # and writes json report for coveralls.io
      - run: luacov-coveralls -o lua_coverage_report.json --dryrun

      - *capture_coverage_data

      # Share coverage data between jobs
      - save_cache:
          key: coverage-functional-{{ .Environment.CIRCLE_WORKFLOW_ID }}
          paths:
            - coverage.functional.dump
            - lua_coverage_report.json

      - store_artifacts:
          path: output.xml
      - store_artifacts:
          path: log.html
      - store_artifacts:
          path: report.html

      - run: mkdir -p test-results; mv xunit.xml test-results
      - store_test_results:
          path: test-results

      - run: (exit $RETURN_CODE)

  eslint:
    docker:
      - image: circleci/node:latest
    steps:
      - checkout
      - restore_cache:
          keys:
          - v1-dependencies-{{ checksum "package.json" }}
          # fallback to using the latest cache if no exact match is found
          - v1-dependencies-
      - run: npm install
      - save_cache:
          paths:
            - node_modules
          key: v1-dependencies-{{ checksum "package.json" }}
      - run: ./node_modules/.bin/eslint -v && ./node_modules/.bin/eslint ./

  tidy:
    docker:
      - image: buildpack-deps:latest
    steps:
      - run:
          name: Exporting env vars
          command: |
            cat >> $BASH_ENV <<EOF
            export PATH=$PATH:$HOME/perl5/bin
            export PERL_CPANM_OPT=--local-lib=$HOME/perl5
            export PERL5LIB=$HOME/perl5/lib/perl5:$PERL5LIB
            EOF
      - checkout

      - restore_cache:
          key: v0-tidyall_dependencies
      - run:
          name: Installing cpanm
          command: 'curl -L https://cpanmin.us | perl - App::cpanminus'
      - run:
          name: Installing CPAN dependencies
          command: |
            cpanm --quiet --notest \
              Code::TidyAll \
              Code::TidyAll::Plugin::Test::Vars \
              Perl::Critic \
              Perl::Tidy \
              Pod::Tidy
      - save_cache:
          key: v0-tidyall_dependencies
          paths:
            - ~/perl5
      - run: tidyall -a --check-only

  send-coverage:
    <<: *defaults
    steps:
      - attach_workspace:
          at: *workspace_root
      - restore_cache:
          key: coverage-rspamd-test-{{ .Environment.CIRCLE_WORKFLOW_ID }}
      - restore_cache:
          key: coverage-functional-{{ .Environment.CIRCLE_WORKFLOW_ID }}

      - *merge_and_upload_coverage_data

      - store_artifacts:
          path: out.josn

notify:
  webhooks:
    - url: https://coveralls.io/webhook?repo_token={{ .Environment.COVERALLS_REPO_TOKEN }}

workflows:
  version: 2
  build-and-test:
    jobs:
      - build
      - eslint
      - tidy
      - rspamd-test:
          requires:
            - build
      - functional:
          requires:
            - build
      - send-coverage:
          requires:
            - rspamd-test
            - functional
