#!/usr/bin/env zsh
# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
# vim: ft=zsh sw=2 ts=2 et
#
# This file runs the highlighter on a specified file
# i.e. parses the file with the highlighter. Outputs
# running time (stderr) and resulting region_highlight
# (file parse.out, or $2 if given).
#
# Can be also run in line-wise mode on own input (-o
# option in $1), no region_highlight file then.

0="${ZERO:-${${0:#$ZSH_ARGZERO}:-${(%):-%N}}}"
0="${${(M)0:#/*}:-$PWD/$0}"

ZSH_BIN="$(which zsh)"
SET_FPATH="${0:h}/../../functions"
[[ -z "$FAST_WORK_DIR" ]] && FAST_WORK_DIR="${0:h}"
[[ -z "$ZSH_VERSION" ]] && exec $ZSH_BIN zsh -f -c "source \"$0\" \"$1\" \"$2\" \"$3\""

if [[ ! -e "$FAST_WORK_DIR/secondary_theme.zsh" ]]; then
  cp -f "${0:h}/../free_theme.zsh" "$FAST_WORK_DIR/secondary_theme.zsh"
fi

if [[ -e "$SET_FPATH/fast-highlight" ]]; then
  source "$SET_FPATH/fast-highlight"
  source "$SET_FPATH/fast-string-highlight"
  fpath+=( "$SET_FPATH" )
else
  print -u2 "Could not find fast-highlight, aborting"
  exit 1
fi

zmodload zsh/zprof
autoload is-at-least chroma/-git.ch
builtin setopt interactive_comments extended_glob typeset_silent no_short_loops rc_quotes no_auto_pushd

# Own input?
if [[ "$1" = "-o" || "$1" = "-oo" || "$1" = "-ooo" || "$1" = "-git" || "$1" = "-hue" || "$1" = "-hol" ]]; then
  typeset -a input
  input=()
  if [[ "$1" = "-o" ]]; then
    input+=( "./parse.zsh ../functions/fast-highlight parse2.out" )
    input+=( "rm -f parse*.out" )
    input+=( "./mh-parse.zsh ../functions/fast-highlight > out" )
    input+=( "if [[ -o multibyte ]]; then echo multibyte is set; fi" )
    input+=( "[[ \"a\" = *[[:alpha:]_-][[:alpha:]]# ]] && echo yes" )
    input+=( 'git tag -a v0.98 -m "Syntax highlighting of the history entries"' )
    input+=( 'func() { echo "a" >! phist2.db; echo "b" >>! phist2.db; fc -Rap "phist2.db"; list=( ${history[@]} ); echo "${history[1]}"; }' )
    (( ${+ZSH_EXECUTION_STRING} == 0 )) && { print -zr "${(F)input}"; return 0; }
  elif [[ "$1" = "-oo" ]]; then
    input+=( 'typeset -a list\n() {\necho "a" >! phist2.db\necho "b" >>! phist2.db\nfc -Rap "phist2.db"\nlist=( ${history[@]} )\necho "${history[2]}"\necho "${history[1]}"\necho "${#history}";\ninteger size="${#history}"\nsize+=1\necho "$size" / "${history[$size]}"\nlist=( "${history[$size]}" ${history[@]} )\n}' )
    input+=( 'typeset -a list\n() {\necho "a" >! phist2.db\necho "b" >>! phist2.db\nfc -Rap "phist2.db"\nlist=( ${history[@]} )\necho "${history[2]}"\necho "${history[1]}"\necho "${#history}";\ninteger size="${#history}"\nsize+=1\necho "$size" / "${history[$size]}"\nlist=( "${history[$size]}" ${history[@]} )\n}' )
    input+=( 'typeset -a list\n() {\necho "a" >! phist2.db\necho "b" >>! phist2.db\nfc -Rap "phist2.db"\nlist=( ${history[@]} )\necho "${history[2]}"\necho "${history[1]}"\necho "${#history}";\ninteger size="${#history}"\nsize+=1\necho "$size" / "${history[$size]}"\nlist=( "${history[$size]}" ${history[@]} )\n}' )
    input+=( 'typeset -a list\n() {\necho "a" >! phist2.db\necho "b" >>! phist2.db\nfc -Rap "phist2.db"\nlist=( ${history[@]} )\necho "${history[2]}"\necho "${history[1]}"\necho "${#history}";\ninteger size="${#history}"\nsize+=1\necho "$size" / "${history[$size]}"\nlist=( "${history[$size]}" ${history[@]} )\n}' )
    input+=( 'typeset -a list\n() {\necho "a" >! phist2.db\necho "b" >>! phist2.db\nfc -Rap "phist2.db"\nlist=( ${history[@]} )\necho "${history[2]}"\necho "${history[1]}"\necho "${#history}";\ninteger size="${#history}"\nsize+=1\necho "$size" / "${history[$size]}"\nlist=( "${history[$size]}" ${history[@]} )\n}' )
    input+=( 'typeset -a list\n() {\necho "a" >! phist2.db\necho "b" >>! phist2.db\nfc -Rap "phist2.db"\nlist=( ${history[@]} )\necho "${history[2]}"\necho "${history[1]}"\necho "${#history}";\ninteger size="${#history}"\nsize+=1\necho "$size" / "${history[$size]}"\nlist=( "${history[$size]}" ${history[@]} )\n}' )
    input+=( 'typeset -a list\n() {\necho "a" >! phist2.db\necho "b" >>! phist2.db\nfc -Rap "phist2.db"\nlist=( ${history[@]} )\necho "${history[2]}"\necho "${history[1]}"\necho "${#history}";\ninteger size="${#history}"\nsize+=1\necho "$size" / "${history[$size]}"\nlist=( "${history[$size]}" ${history[@]} )\n}' )
    (( ${+ZSH_EXECUTION_STRING} == 0 )) && { print -zr "${(F)input}"; return 0; }
  elif [[ "$1" = "-ooo" ]]; then
    local in='
# This is an example code that is diverse and allows to test a theme
text="An example quite long string $with variable in it"
local param1="text $variable" param2='"'"'other $variable'"'"'
math=$(( 10 + HISTSIZ + HISTSIZE + $SAVEHIST )) size=$(( 0 ))

for (( ii = 1; ii <= size; ++ ii )); do
  if [[ "${cmds[ii]} string" = "| string" ]]
  then
    sidx=${buffer[(in:ii:)\$\(?#[^\\\\]\)]} # find opening $(
    (( sidx <= len )) && {
      eidx=${buffer[(b:sidx:ii)[^\\\\]\)]} # find closing )
    }
  fi
done'
    (( ${+ZSH_EXECUTION_STRING} == 0 )) && { print -zr "$in"; return 0; }
    input+=( "$in" )
    input+=( "$in" )
  elif [[ "$1" = "-git" ]]; then
    local in="git lp
git push origin main
git commit
git add safari.ini zdharma.ini
git st .
git diff --cached
git commit --allow-empty
git checkout themes/zdharma.ini
git commit --amend
git commit -m \"Example commit message\"
git tag -a 'v1.18' -m 'Here-string is highlighted, descriptor-variables passed to exec are correctly highlighted'
git tag -l -n9
git checkout cb66b11
"
    (( ${+ZSH_EXECUTION_STRING} == 0 )) && { print -zr "$in"; return 0; }
    input+=( "$in" )
    input+=( "$in" )
  elif [[ "$1" = "-hue" ]]; then
    local in="var=\$other; local var=\$other
    () { eval \"\$var\"; }
    case \$other in
      \$var)
        ( echo OK; )
        ;;
    esac
    sudo -i -s ls -1 /var/log
    () { ( eval \"command ls -1\" ); } argument"

    (( ${+ZSH_EXECUTION_STRING} == 0 )) && { print -zr "$in"; return 0; }

    input+=( "$in" "$in" )
  elif [[ "$1" = "-hol" ]]; then
    local in="var=\$( other )
local var2=\$(( other + 1 ))
() { eval \"\$var\"; }
sudo -i -s ls -1 >/tmp/ls-log.txt /var/log
IFS=\$'\\n' print -rl -- \$(command ls -1 | tee -a /tmp/ls-1.txt)
var3=\$(( HISTSIZE + 10 + \$var ))
local var4=\$( other command )
touch \$(( HISTSIZE + \$SAVEHIST + 10 ))
case \$other in
  \$var)
    ( echo OK; )
    ;;
  \$var3)
    ( if { true } { noglob echo yes } )
esac
( builtin cd /var/log; ls -1; noglob cd \"/var/log\" 'log' )
noglob cat <<<\"\$PATH\" | tr : \"\\n\"
if [[ \"\$var\" -gt 10 ]]; then
  (( var = HISTSIZE + \$SAVEHIST ))
fi
/var/log
sidx=\${buffer[(in:ii:)\\\$\\(?#[^\\\\\\\\]\\)]} # find opening cmd-subst
{
  exec {MYFD}<&0 {MYFD2}>&1
  ( read <&\$MYFD line; echo \$line >&\$MYFD2 && { builtin print \${match[1]}Written. } )
} always {
  (( MYFD > 0 )) && { print -rl -- -myfd:\$MYFD >&\$MYFD2 && print \"Sent.\" '(to filedescriptor)'; }
}
command sleep \"\$(( \$a + b + \${cde} + \${(s::)fgh[ijk]} + \\\$l + \\m + \\\"  ))\"
for (( i = 0; i <= 2; ++ i )) { print \$i; }
"

    (( ${+ZSH_EXECUTION_STRING} == 0 )) && { print -zr "$in"; return 0; }

    input+=( "$in" )
  fi

  typeset -a long_input
  integer i
  for (( i=1; i<= 50; i ++ )); do
    long_input+=( "${input[@]}" )
  done

  typeset -F SECONDS
  SECONDS=0

  local right_brace_is_recognised_everywhere
  integer path_dirs_was_set multi_func_def ointeractive_comments
  -fast-highlight-fill-option-variables

  local BUFFER
  for BUFFER in "${long_input[@]}"; do
    reply=( )
    () {
      -fast-highlight-init
      -fast-highlight-process "" "$BUFFER" "0"
      -fast-highlight-string-process "" "$BUFFER"
    }
  done

  print "Running time: $SECONDS"
  zprof | head
# File input?
elif [[ -r "$1" ]]; then
  # Load from given file
  local BUFFER="$(<$1)"

  typeset -F SECONDS
  SECONDS=0

  reply=( )
  -fast-highlight-init

  local right_brace_is_recognised_everywhere
  integer path_dirs_was_set multi_func_def ointeractive_comments
  -fast-highlight-fill-option-variables

  () {
    -fast-highlight-process "" "$BUFFER" "0"
    -fast-highlight-string-process "" "$BUFFER"
  }

  print "Running time: $SECONDS"
  zprof | head

  # This output can be diffed to detect changes in operation
  if [[ -z "$2" ]]; then
      print -rl -- "${reply[@]}" >! out.parse
  else
      print -rl -- "${reply[@]}" >! "$2"
  fi
else
  if [[ -z "$1" ]]; then
    print -u2 "Usage: fast-parse {to-parse file} [region_highlight output file]"
    exit 2
  else
    print -u2 "Unreadable to-parse file \`$1', aborting"
    exit 3
  fi
fi

exit 0
