#!/usr/bin/bash

OUTPUT_REGULAR=reports/lint-regular-report.txt
OUTPUT_LEGACY=reports/lint-legacy-report.txt
OUTPUT_FINAL=reports/lint-common-report.txt

OUTPUT_MR=reports/lint-mr-report.txt

LINE_CHANGES=changed-lines.txt

is_empty() {
  (! grep -q . $1)
}

run_eslint() {
  ARGS_LEGACY='--config lint/eslintrc-legacy.json'

  local extra_args=ARGS_$1
  local output=OUTPUT_$1
  eslint -f unix ${!extra_args} -o ${!output} js
}

list_commit_range_additions() {
  # Turn raw context-less git-diff into a list of
  # filename:lineno pairs of new (+) lines
  git diff -U0 "$@" -- js |
  awk '
    BEGIN { file=""; }
    /^+++ b/ { file=substr($0,7); }
    /^@@ / {
        len = split($3,a,",")
        start=a[1]
        count=(len > 1) ? a[2] : 1

        for (line=start; line<start+count; line++)
            printf "%s/%s:%d:\n",ENVIRON["PWD"],file,line;
    }'
}

copy_matched_lines() {
  local source=$1
  local matches=$2
  local target=$3

  echo -n > $target
  for l in $(<$matches); do
    grep $l $source >> $target
  done
}

create_common() {
  # comm requires sorted input;
  # we also strip the error message to make the following a "common" error:
  # regular:
  #  file.js:42:23 Indentation of 55, expected 42
  # legacy:
  #  file.js:42:23 Indentation of 55, extected 24
  prepare() {
    sed 's: .*::' $1 | sort
  }

  comm -12 <(prepare $OUTPUT_REGULAR) <(prepare $OUTPUT_LEGACY) >$OUTPUT_FINAL.tmp

  # Now add back the stripped error messages
  copy_matched_lines $OUTPUT_REGULAR $OUTPUT_FINAL.tmp $OUTPUT_FINAL
  rm $OUTPUT_FINAL.tmp
}

if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
  commit_range=origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME...$CI_COMMIT_SHA
  list_commit_range_additions $commit_range > $LINE_CHANGES

  # Don't bother with running lint when no JS changed
  if is_empty $LINE_CHANGES; then
    exit 0
  fi
fi

echo Generating lint report using regular configuration
run_eslint REGULAR
echo Generating lint report using legacy configuration
run_eslint LEGACY
echo Done.
create_common

# Just show the report and succeed when not testing a MR
if [ -z "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
  cat $OUTPUT_FINAL
  exit 0
fi

copy_matched_lines $OUTPUT_FINAL $LINE_CHANGES $OUTPUT_MR
cat $OUTPUT_MR
is_empty $OUTPUT_MR