@echo off

rem Detect processor archietcture
set bindir=
if "%PROCESSOR_ARCHITECTURE%" == "x86" set bindir=bin
if "%PROCESSOR_ARCHITECTURE%" == "AMD64" set bindir=bin64
if "%bindir%" == "" (
  echo Unsupported processor architecture: %PROCESSOR_ARCHITECTURE%
  exit /b
)

rem Whether to stop on first error during check.
rem Set to not-empty value to stop.
set stop_on_first_error=

rem Lets check if command processor supports extensions that we need
rem Also make all environment variable changes local and enable delayed expansion 
verify other 2> nul
setlocal enableextensions 
setlocal enabledelayedexpansion
if errorlevel 1 goto unsupported
goto proceed
:unsupported
echo COMMAND EXTENSIONS ARE NOT AVAILABLE. 
echo TEST TOOL WILL NOW TERMINATE.
goto terminate

:proceed
set tcmd=%~f0

if /i "%1" == "build" goto build
if /i "%1" == "check" goto check
if /i "%1" == "xml" goto xml
if /i "%1" == "challenge_xml_part" goto challenge_xml_part
if /i "%1" == "pcms" goto pcms
if /i "%1" == "archive" goto archive
if /i "%1" == "clean" goto clean
if /i "%1" == "make" goto make
if /i "%1" == "run" goto run
if /i "%1" == "time" goto time
if /i "%1" == "help" goto help
if /i "%1" == "" goto shorthelp

echo Unrecognized command "%1".
echo Use "t help | more" for help.
exit /b

rem --------------------------------- HELP ---------------------------------

:shorthelp
echo TEST TOOL. (C) Roman Elizarov, 2004-2010
echo Use "t help | more" for help.
exit /b

:help
echo =========================================================================
echo TEST TOOL. (C) Roman Elizarov, 2004-2010,
echo            Contibutions from: Georgy Korneev, Maxim Babenko, and others
echo Usage: t [^<subcommand^> [^<arguments^>...]]
echo "t help" shows this help. Other available subcommands are:
echo build, check, xml, pcms, clean, make, run, time 
echo (case is not important for subcommands).
echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
echo DIRECTORY STRUCTURE
echo Test tool assumes that each directory with problem has "tests"
echo subdirectory with test files that are named 01, 02, 03,..., 99.
echo Alternatively, instead of "XX" test file it may contain "doXX.dpr"
echo file that prints to the console contents of the corresponding test.
echo Alternatively, it may contain "doall.*" instead of all tests
echo "doall" shall create ALL test files and may assume that it is being 
echo called from the tests directory. Alternatively (recommended way), the 
echo problem directry may contain "Tests.java" that creates "tests" directly 
echo with all the neccessary test files.
echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
echo Answer files are placed into "XX.a" files after build. They are 
echo generated by running a specified model solution.
echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
echo Build, check, and clean subcommands may be used from the top-level
echo directory. They always recursively scan subdirectories for problem
echo directories and perform their task for each problem.
echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
echo SPECIFYING SOLUTION
echo Build and check subcommands accept solution as their first and only
echo argument. Source or executable file with solution may be explicitly
echo specified (see make subcommand for a list of supported extensions).
echo For example, "t build solution.dpr" will build answer files using
echo "solution.dpr". Suffix for the solution name may be specified
echo instead. In this case, problem and underscore are appended before the
echo specified suffix. For example, "t build re.dpr" for problem called
echo "box" will generate answers using "box_re.dpr". Extension may be
echo omitted in the suffix, so the last command may be shortened to just
echo "t build re". Combined with recursive behavior one can run it in the
echo top-level directory to check all problems with solutions that have
echo "re" suffix. If solution is omitted entirely, then problem name is
echo used instead. For example "t build" for problem called "box" will
echo generate answer using "box.dpr", or "box.java", or "box.cpp", etc if
echo one of the corresponding files exits.
echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
echo BUILD
echo Usage: t build [^<solution^> [^<tests^>...]]
echo Builds test files and answer files. It creates "t-build.log" file
echo where outcome for each test is listed (one test on a line). If
echo solution is not found, then answer files are not generated. Works
echo for all available tests unless the the list of tests is explicitly 
echo specified. When all tests are being built it also compiles checker
echo program named "check" if it exists.
echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
echo CHECK
echo Usage: t check [^<solution^> [^<tests^>...]]
echo Checks specified solution. It creates "t-check.log" file where outcome
echo for each test is listed (one test on a line). Checker program shall be
echo named "check" and shall accept "input output answer" arguments in this
echo order. Works with all available tests unless the list of tests is 
echo explicitly specified.
echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
echo XML
echo Usage: t xml [^<prefix^> [^<time-limit^> [^<memory-limit^>]]]
echo Builds "problem.xml", so that problem can be used with PCMS2-v2
echo contest management system. You must successfully use build subcommand
echo before using xml subcommand. Prefix is prepended to problem identifiers
echo (default is empty). Default time limit is 2s, memory limit 67108864.
echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
echo PCMS
echo Usage: t pcms
echo Copies all PCMS configuration files (problem.xml, tests, checker) into a 
echo separate directory. You must "build" and "xml" first.
echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
echo ARCHIVE
echo Usage: t pcms
echo Copies correct solutions into a echo separate directory.
echo You must "build" and "xml" first.
echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
echo CLEAN
echo Usage: t clean
echo Cleans all auxiliary files that might have been created during build,
echo xml, and check operations.
echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
echo MAKE
echo Usage: t make ^<srcfile^>
echo Makes the specified source file. Supported extensions are .java, .dpr,
echo .cpp, .c, .hs, .ml, .py, .cmd, .exe. In the later cases (.py, .cmd, .exe)
echo make just silently quits. Extension may be entirely omitted. In this case
echo make will try echo to find the file by attaching extensions in the order
echo they are listed above. For example, "t make solution" will compile
echo "solution.dpr" file (if it exits) using Borland Delphi. During compilation
echo it includes "..\testlib" directory (relative to the directory of the main
echo "t.cmd" file) into the compilation path. Any additional libraries that
echo are common to all problems shall be stored there.
echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
echo RUN
echo Usage: t run ^<srcfile^> [^<arguments^>...]
echo Runs the specified source or executable file. It assumes that the
echo source file is already compiled using make subcommand and uses the
echo corresponding command to run it. For example, "t run solution.dpr"
echo will actually run "solution.exe", while "t run solution.java" will
echo actually run "java solution". Extension may be omitted just like in
echo make subcommand. 
echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
echo TIME
echo Usage: t time ^<srcfile^> [^<arguments^>...]
echo Works like run subcommand, but execution is wrapped into 
echo "..\bin\run.exe -q -x" call (relative to the directory of the main 
echo "t.cmd" file) if the corresponding wrapper file exists, otherwise 
echo run is performed directly. It will wraps the run into coact/interact
echo pair for interactive problems.
echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
echo FEEDBACK
echo Please report all bugs and suggestions for this tool to Roman Elizarov
echo using email elizarov@gmail.com
echo =========================================================================
exit /b

rem --------------------------------- BUILD ---------------------------------

:build
if not exist tests (
  if not exist Tests.java (
    rem Recurse through subdirs
    echo Scanning %CD%
    call :rec_sub %*
    exit /b
  )
)

for %%i in (%CD%) do set problem=%%~ni
echo Building problem %problem.id% in %CD%

del t-build.log 2> nul
del t-run.log 2> nul

call :load_problem_properties
if "%2" == "*" (
  set srcfile=%problem.solution%
) else if "%2" == "" (
  set srcfile=%problem.solution%
) else (
  set srcfile=%2
)

set testnos=%3
:build_testnos
shift
if "%3" == "" goto build_done_testnos
set testnos=%testnos% %3
goto build_testnos
:build_done_testnos

rem Always run "Tests.java" if it exists
if exist Tests.java (
  call %tcmd% make Tests.java
  call %tcmd% run Tests.java
)

rem Always run "doall" if it exists
call :expand tests/doall
if exist %result% (
  pushd tests
  rem Make sure all tests are clean before rerunning "doall"
  for /l %%i in (0,1,9) do for /l %%j in (0,1,9) do del %%i%%j 2> nul
  call %tcmd% make doall
  call %tcmd% run doall
  popd
)

if "%testnos%" == "" (
  rem If generating all tests, then also make checker
  call %tcmd% make check
  rem And actually all tests themselves
  for /l %%i in (0,1,9) do for /l %%j in (0,1,9) do call :build_generate_sub %%i%%j
) else (
  for %%i in (%testnos%) do call :build_generate_sub %%i
)

call %tcmd% make interact quiet
if errorlevel 1 (
  rem NOT AN INTERACTIVE PROBLEM
) else (
  echo INTERACTIVE PROBLEM
)

rem figure out what solution to use
call :resolve_solution_sub

if not exist %srcfile% (
  echo NO SOLUTION FOUND FOR PROBLEM %problem.id%.
  exit /b
)

:build_solution_found
echo Building answer files with %srcfile%
call %tcmd% make %srcfile%
if errorlevel 1 (
  echo Failed to make %srcfile%. Will not build answer files.
  exit /b
)

set success=true
if "%testnos%" == "" (
  for /l %%i in (0,1,9) do for /l %%j in (0,1,9) do (
    call :build_ans_sub %%i%%j
  )
) else (
  for %%i in (%testnos%) do (
    call :build_ans_sub %%i
  ) 
)

del %problem.input% 2> nul
del %problem.output% 2> nul
del %problem.log% 2> nul

if "%success%" == "true" (
  echo BUILD SUCCESSFUL FOR PROBLEM %problem.id%.
  exit /b 0
) else (
  echo BUILD FAILED FOR PROBLEM %problem.id%. See t-build.log.
  exit /b 1
)

:build_generate_sub
if not exist tests\do%1.dpr goto :testjava
echo Generating problem %problem.id% test %1.
del tests\%1 2> nul
del tests\%1.a 2> nul
del tests\%1.b 2> nul
call %tcmd% make tests\do%1.dpr
if errorlevel 1 (
  echo Failed to genereate problem %problem.id% test %1.
) else (
  call %tcmd% run tests\do%1.exe > tests\%1
  del tests\do%1.exe 2> nul
)
exit /b
:testjava
if not exist tests\do%1.java exit /b
echo Generating problem %problem.id% test %1.
del tests\%1 2> nul
del tests\%1.a 2> nul
del tests\%1.b 2> nul
pushd tests
call %tcmd% make do%1.java
popd
if errorlevel 1 (
  echo Failed to genereate problem %problem.id% test %1.
) else (
  pushd tests
  call %tcmd% run do%1.java > %1
  del do%1.class 2> nul
  popd
)
exit /b

:build_ans_sub
if not exist tests\%1 exit /b
echo Running %srcfile% on problem %problem.id% test %1.
del %problem.output% 2> nul
del %problem.log% 2> nul
copy tests\%1 %problem.input% > nul
call %tcmd% time %srcfile%
if errorlevel 1 (
  call :testlogerror build %1
  set success=false
) else (
  if exist %problem.log% (
    copy %problem.log% tests\%1.b > nul
  )
  if exist %problem.output% (
    copy %problem.output% tests\%1.a > nul
    call %tcmd% run check %problem.input% %problem.output% tests\%1.a
    call :testlog build %1 Done
  ) else (
    call :testlog build %1 Failed to create output
    set success=false
  )
)
exit /b

rem --------------------------------- CHECK ---------------------------------

:check
if not exist tests (
  if not exist Tests.java (
    rem Recurse through subdirs
    echo Scanning %CD%
    call :rec_sub %*
    exit /b
  )
)

for %%i in (%CD%) do set problem=%%~ni
echo Checking problem %problem.id% in %CD%

del t-check.log 2> nul
del t-run.log 2> nul
del run.dat 2> nul

call :load_problem_properties
if [%2] == [*] (
    set srcfile=%problem.solution%
) else (
    set srcfile=%2
)

set testnos=%3

:check_testnos
shift
if "%3" == "" goto check_done_testnos
set testnos=%testnos% %3
goto check_testnos
:check_done_testnos

call %tcmd% make check
if errorlevel 1 (
  echo CHECK FAILED FOR PROBLEM %problem.id%. Cannot make check.
  exit /b 1
)

call %tcmd% make interact quiet
if errorlevel 1 (
  rem NOT AN INTERACTIVE PROBLEM
) else (
  echo INTERACTIVE PROBLEM
)

rem figure out what solution to use
call :resolve_solution_sub

call %tcmd% make %srcfile%
if errorlevel 1 (
  echo CHECK FAILED FOR PROBLEM %problem.id%. Cannot make %srcfile%.
  exit /b 1
)

set success=true
if "%testnos%" == "" (
    for /l %%i in (0,1,9) do for /l %%j in (0,1,9) do (
        call :check_sub %%i%%j
        if not "%stop_on_first_error%" == "" (
            if not "!success!" == "true" goto check_exit_loop
        )
    )
) else (
    for %%i in (%testnos%) do call :check_sub %%i
)
:check_exit_loop

del %problem.input% 2> nul
del %problem.output% 2> nul
del %problem.log% 2> nul

if not exist run.dat goto skip_statistics
    call :load_properties run.dat statistics
    echo MAX TIME IS: %statistics.max.timeConsumed%ms
    echo MAX MEMORY IS: %statistics.max.memoryConsumed%B
:skip_statistics

if "%success%" == "true" (
  echo CHECK SUCCESSFUL FOR PROBLEM %problem.id%.
  exit /b 0
) else (
  echo CHECK FAILED FOR PROBLEM %problem.id%. See t-check.log.
  exit /b 1
)

:check_sub
if not exist tests\%1 exit /b
echo Running %srcfile% on problem %problem.id% test %1.
del %problem.output% 2> nul
del %problem.log% 2> nul
copy tests\%1 %problem.input% > nul
call %tcmd% time %srcfile%
if errorlevel 1 (
  call :testlogerror check %1
  set success=false
) else (
  if exist tests\%1.a (
    call %tcmd% run check %problem.input% %problem.output% tests\%1.a
    if errorlevel 1 (
      call :testlog check %1 Check has not accepted solution
      set success=false
    ) else (
      call :testlog check %1 Done
    )
  ) else (
    call :testlog check %1 Answer file is not found
    set success=false
  )
)
exit /b

rem --------------------------------- XML ---------------------------------

:xml

if exist contest.properties (
    call :challenge_xml_print %* > challenge.xml
)

if not exist tests (
  if not exist Tests.java (
    rem Recurse through subdirs
    echo Scanning %CD%
    call :rec_sub %*
    exit /b
  )
)

for %%i in (%CD%) do set problem=%%~ni
call :load_contest_properties
call :load_problem_properties
echo XML for problem %problem.id% in %CD%

del problem.xml 2> nul

set prefix=%~2
if "%prefix%" == "" set prefix=%contest.problem-prefix%.
if "%timelimit%" == "" set timelimit=%problem.timelimit%
if "%timelimit%" == "" set timelimit=%contest.timelimit%

if "%memorylimit%" == "" set memorylimit=%problem.memorylimit%
if "%memorylimit%" == "" set memorylimit=%contest.memorylimit%

if exist check.jar  (
  set checkerstring=                ^^^<binary executable-id = "java.check" file = "Check.jar" /^^^>
) else if exist check.exe (
  set checkerstring=                ^^^<binary executable-id = "x86.exe.win32" file = "check.exe" /^^^>
) else (
  echo XML FAILED FOR PROBLEM %problem.id% -- must build first, check.exe/jar is missing.
  exit /b 1
)

set lasttest=
set testcount=0
for /l %%i in (0,1,9) do for /l %%j in (0,1,9) do (
  if exist tests\%%i%%j (
    if not exist tests\%%i%%j.a (
      echo XML FAILED FOR PROBLEM %problem.id% -- must build first, answer is missing.
      exit /b 1
    )
    set lasttest=%%i%%j
    call :xml_inc_testcount
  ) else if exist tests\do%%i%%j.dpr (
    echo XML FAILED FOR PROBLEM %problem.id% -- must build first, test is missing.
    exit /b 1
  )
)

if "%lasttest:~0,1%" == "0" set lasttest=%lasttest:~1%

if "%lasttest%" NEQ "%testcount%" (
  echo XML FAILED FOR PROBLEM %problem.id% -- noncontiguous test set.
  exit /b 1
)

call :xml_print > problem.xml
echo XML SUCCESSFUL FOR PROBLEM %problem.id%.
exit /b

:xml_inc_testcount
set /a testcount=%testcount%+1
exit /b

:xml_print
call :banner problem.xml ""
echo.
echo ^<problem
echo     id      = "%prefix%%problem.id%"
echo     version = "1.0"
echo ^>
echo     ^<judging^>
echo         ^<script type = "%%icpc"^>
echo             ^<testset
echo                 test-count   = "%testcount%"
echo                 input-href   = "tests/##"
echo                 answer-href  = "tests/##.a"
echo                 input-name   = "%problem.input%"
echo                 output-name  = "%problem.output%"
echo                 time-limit   = "%timelimit%"
echo                 memory-limit = "%memorylimit%"
echo             /^>
echo             ^<verifier type = "%%testlib"^>
echo %checkerstring%
echo             ^</verifier^>
echo         ^</script^>
echo     ^</judging^>
echo ^</problem^>

exit /b

:challenge_xml_print
call :load_contest_properties contest.properties

set prefix=%~2
if "%prefix%" == "" set prefix=%contest.problem-prefix%

echo ^<challenge
echo     id              = "%contest.id%"
echo     name            = "%contest.name-1%, %contest.name-2%"
echo     scoring-model   = "%%icpc"
echo     length          = "5h"
echo.
echo     problem-id      = "%prefix%"
echo     xmlai-process   = "http://neerc.ifmo.ru/develop/pcms2/xmlai/default-rules.xml"
echo ^>
call :rec_sub challenge_xml_part
echo ^</challenge^>
exit /b

:challenge_xml_part
    for %%i in (%CD%) do set problem=%%~ni
    call :load_problem_properties
    echo     ^<problem-ref id = "%problem.short-id%" alias = "%problem.alias%" problem-id = "%problem.id%" name = "%problem.name%"/^>
exit /b


rem --------------------------------- PCMS ---------------------------------

:pcms
if [%dir%]==[] (
    set dir=%~dp0
)

if exist challenge.xml (
    if not exist %dir%\__pcms mkdir %dir%\__pcms\
    copy challenge.xml %dir%\__pcms\* > nul
)

if not exist tests (
  if not exist Tests.java (
    rem Recurse through subdirs
    echo Scanning %CD%
    call :rec_sub %*
    if exist challenge.xml copy challenge.xml %dir%\__pcms\ > nul
    exit /b
  )
)

for %%i in (%CD%) do set problem=%%~ni
call :load_problem_properties
echo PCMS for problem %problem.id% in %CD%

if not exist check.exe (
  if not exist check.jar (
    echo PCMS FAILED FOR PROBLEM %problem.id% -- must build first, check.exe/jar is missing.
    exit /b 1
  )
)

if not exist problem.xml (
  echo PCMS FAILED FOR PROBLEM %problem.id% -- must build xml first, problem.xml is missing
  exit /b 1
)

set lasttest=
set testcount=0
for /l %%i in (0,1,9) do for /l %%j in (0,1,9) do (
  if exist tests\%%i%%j (
    if not exist tests\%%i%%j.a (
      echo PCMS FAILED FOR PROBLEM %problem.id% -- must build first, answer is missing.
      exit /b 1
    )
    set lasttest=%%i%%j
    call :xml_inc_testcount
  ) else if exist tests\do%%i%%j.dpr (
    echo PCMS FAILED FOR PROBLEM %problem.id% -- must build first, test is missing.
    exit /b 1
  )
)

if "%lasttest:~0,1%" == "0" set lasttest=%lasttest:~1%

if "%lasttest%" NEQ "%testcount%" (
  echo XML FAILED FOR PROBLEM %problem.id% -- noncontiguous test set.
  exit /b 1
)

echo Copying %testcount% tests

if not exist %dir%\__pcms\%problem.id%\ mkdir %dir%\__pcms\%problem.id%
if not exist %dir%\__pcms\%problem.id%\tests\ mkdir %dir%\__pcms\%problem.id%\tests\
for /l %%i in (0,1,9) do for /l %%j in (0,1,9) do (
  if exist tests\%%i%%j (
    copy tests\%%i%%j %dir%\__pcms\%problem.id%\tests\ > nul
    copy tests\%%i%%j.a %dir%\__pcms\%problem.id%\tests\ > nul
  )
)

echo Copying problem.xml
copy problem.xml %dir%\__pcms\%problem.id%\ > nul

echo Copying check and interact
for %%b in (check.jar interact.jar check.exe interact.exe) do (
  copy %%b %dir%\__pcms\%problem.id%\ > nul
)

for %%b in (Check.java Interact.java check.dpr interact.dpr) do (
  if exist %%b (
    call :banner %%b "%problem.checker%" > %dir%__pcms\%problem.id%\%%b
    echo. >> %dir%__pcms\%problem.id%\%%b
    type %%b >> %dir%__pcms\%problem.id%\%%b
  )
)

echo PCMS SUCCESSFUL FOR PROBLEM %problem.id%.
exit /b

rem ------------------------------- ARCHIVE --------------------------------

:archive
if [%dir%]==[] (
    set dir=%~dp0
)

if not exist tests (
  if not exist Tests.java (
    rem Recurse through subdirs
    echo Scanning %CD%
    call :rec_sub %*
    exit /b
  )
)

for %%i in (%CD%) do set problem=%%~ni
call :load_problem_properties
echo ARCHIVE for problem %problem.id% in %CD%

if not exist check.exe (
  if not exist check.jar (
    echo ARCHIVE FAILED FOR PROBLEM %problem.id% -- must build first, check is missing.
    exit /b 1
  )
)

if not exist problem.xml (
  echo ARCHIVE FAILED FOR PROBLEM %problem.id% -- must build xml first, problem.xml is missing
  exit /b 1
)

if not exist %dir%__pcms\%problem.id% mkdir %dir%__pcms\%problem.id%

for %%a in (java dpr cpp c hs ml py) do (
    for %%b in (%problem.source%_*.%%a) do (
        call %tcmd% check %%b
        if not errorlevel 1 (
            echo Copying solution %%b to archive
            call :banner %%b > %dir%__pcms\%problem.id%\%%b
            if errorlevel 1 (
                type %dir%__pcms\%problem.id%\%%b
                exit /b
            )
            echo. >> %dir%__pcms\%problem.id%\%%b
            type %%b >> %dir%__pcms\%problem.id%\%%b
        )
    )
)

for %%b in (Check.java Interact.java check.dpr interact.dpr) do (
    call :banner %%b "%problem.checker%" > %dir%__pcms\%problem.id%\%%b
    echo. >> %dir%__pcms\%problem.id%\%%b
    type %%b >> %dir%__pcms\%problem.id%\%%b
)

echo ARCHIVE SUCCESSFUL FOR PROBLEM %problem.id%.
exit /b

rem --------------------------------- BANNER --------------------------------

:banner

call :load_contest_properties
call :load_problem_properties

if "[%~1]" == "[]" (
    echo Usage: :banner ^<file name^> ^<author^>
    exit /b 1
)
set file=%~1

if not "[%2]" == "[]" (
    if not "[%~2]" == "[]" (
        set author_initials=%~2
    ) else (
        set author=
        goto :banner_skip_author
    )
)

echo set file_name=%%file:%problem.source%=$%%> temp.cmd
call temp.cmd
del temp.cmd
call :substring_after %file_name% "_"
call :substring_before %substring_after.result% "_"
call :substring_before %substring_before.result% "."
if "%author_initials%" == "" (
    set author_initials=%substring_before.result%
)

set author=
for /f "usebackq tokens=*" %%a in (`echo %%contest.juror.%author_initials%%%`) do (
    set author=%%a
)

if "[%author%]" == "[%%contest.juror.%author_initials%%%]" (
    echo Cannot find author for %file%.
    echo Author initials: %author_initials%
    exit /b 1
)

:banner_skip_author

set banner.language=
if "%file:~-5%" == ".java"  set banner.language=c
if "%file:~-4%" == ".dpr"   set banner.language=delphi
if "%file:~-2%" == ".cpp"   set banner.language=c
if "%file:~-4%" == ".c"     set banner.language=c
if "%file:~-3%" == ".hs"    set banner.language=haskell
if "%file:~-3%" == ".ml"    set banner.language=delphi
if "%file:~-3%" == ".py"    set banner.language=python
if "%file:~-4%" == ".xml"   set banner.language=xml
if "%banner.language%" == "" (
    echo Unknown file type: %file%
    exit /b 1
)

call :expand_jurors problem.idea %problem.idea%
call :expand_jurors problem.statement %problem.statement%
call :expand_jurors problem.testset %problem.testset%

call :solidLine 
call :textLine "%contest.name-1%"
call :textLine "%contest.name-2%"
call :textLine "%contest.location%, %contest.date%"
call :solidLine 
call :textLine "Problem %problem.alias%. %problem.name%"
call :textLine ""
call :textLine "Original idea         %problem.idea%"
call :textLine "Problem statement     %problem.statement%"
call :textLine "Testset               %problem.testset%"

if not "%file%" == "problem.xml" (
    call :solidLine
    if /i "%file:~0,5%" == "check" (
        call :textLine "Checker"
    ) else if /i "%file:~0,8%" == "interact" (
        call :textLine "Interact"
    ) else (
        call :textLine "Solution"
    )
    call :textLine ""
    call :textLine "Author                %author%"
)
call :solidLine 

exit /b 0

:solidLine
if [%banner.language%] == [delphi] (
    call :appendBy "(*" "-" "*)"
)
if [%banner.language%] == [c] (
    call :appendBy "/*" "-" "*/"
)
if [%banner.language%] == [haskell] (
    call :appendBy "{-" "-" "-}"
)
if [%banner.language%] == [python] (
    call :appendBy "#" "-" ""
)
if [%banner.language%] == [xml] (
    call :appendByXML "" "="
)
exit /b

:textLine
if [%banner.language%] == [delphi] (
    call :appendBy "(* %~1" " " "*)"
)
if [%banner.language%] == [c] (
    call :appendBy "/* %~1" " " "*/"
)
if [%banner.language%] == [haskell] (
    call :appendBy "{- %~1" " " "-}"
)
if [%banner.language%] == [xml] (
    call :appendByXML " %~1" " "
)
exit /b

:appendBy
set string=%~1
set by=%~2
set last=%~3
set "string=%string%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%"
echo %string:~0,64%%last%
exit /b

:appendByXML
set string=%~1
set by=%~2
set "string=%~1%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%%by%"
setlocal disabledelayedexpansion
echo ^<!--%string:~0,64%--^>
setlocal enabledelayedexpansion
exit /b

rem --------------------------------- CLEAN ---------------------------------

:clean
if not exist tests (
  if not exist Tests.java (
    rem Recurse through subdirs
    echo Scanning %CD%
    call :rec_sub %*
    exit /b
  )
)

echo Cleaning %CD%

if exist Tests.java (
  rmdir /Q /S tests 2> nul
)

call :expand tests\doall
if exist %result% (
  for /l %%i in (0,1,9) do for /l %%j in (0,1,9) do del tests\%%i%%j 2> nul
)
for /l %%i in (0,1,9) do for /l %%j in (0,1,9) do (
  if exist tests\do%%i%%j.dpr (
    del tests\%%i%%j 2> nul
  )
  del tests\%%i%%j.a 2> nul
  del tests\%%i%%j.b 2> nul
)

for %%a in (exe dcu obj class hi o manifest) do (
    del tests\*.%%a 2> nul
    del *.%%a 2> nul
)
del *.in 2> nul
del *.out 2> nul
del *.log 2> nul
del tests.jar 2> nul
del check.jar 2> nul
del interact.jar 2> nul
del run.dat 2> nul
del problem.xml 2> nul
del tests\t-run.log 2> nul
del t-run.err 2> nul
exit /b

rem --------------------------------- MAKE ---------------------------------

:make
set srcfile=%2
call :expand_sub

if /i "%srcfile%" == "Tests.java" (
  rmdir /S /Q __tests 2> nul
  mkdir __tests
  set cp=__tests
  if exist lib (
    pushd lib
    for %%i in (*.jar) do (
      call :append_cp lib\%%i
    )
    popd
  )
)
if /i "%srcfile%" == "Tests.java" (
  call javac -classpath "%cp%" -sourcepath . -d __tests %srcfile% 
  pushd __tests
  call jar cf tests.jar *
  copy /Y tests.jar .. > nul
  popd
  rmdir /S /Q __tests
  exit /b
)
if /i "%srcfile%" == "Check.java" (
  rmdir /S /Q __check 2> nul
  mkdir __check
  call javac -classpath "__check;%~dp0..\testlib\testlib4j.jar" -sourcepath . -d __check %srcfile% 
  pushd __check
  call jar cf check.jar *
  copy /Y check.jar .. > nul
  popd
  rmdir /S /Q __check
  exit /b
)
if /i "%srcfile%" == "Interact.java" (
  rmdir /S /Q __interact 2> nul
  mkdir __interact
  call javac -classpath "__interact" -sourcepath . -d __interact %srcfile% 
  pushd __interact
  call jar cf interact.jar *
  copy /Y interact.jar .. > nul
  popd
  rmdir /S /Q __interact
  exit /b
)
if /i "%srcfile:~-5%" == ".java" (
  call javac -classpath "." %srcfile%
  exit /b
)
if /i "%srcfile:~-4%" == ".dpr" (
  call dcc32 -m -cc -U%~dp0..\testlib\ %srcfile%
  exit /b
)
if /i "%srcfile:~-4%" == ".cpp" (
  call cl /O2 /EHsc -I%~dp0..\testlib\ %srcfile%
  rem call g++ -I "%~dp0..\testlib" -O2 %srcfile% -o "%srcfile:~0,-4%.exe"
  exit /b
)
if /i "%srcfile:~-2%" == ".c" (
  call cl /O2 -I%~dp0..\testlib\ %srcfile%
  exit /b
)
if /i "%srcfile:~-3%" == ".hs" (
  call ghc --make %srcfile%
  del %srcfile:~0,-3%.hi 2> nul
  del %srcfile:~0,-3%.o 2> nul
  del %srcfile:~0,-3%.exe.manifest 2> nul
  exit /b
)
if /i "%srcfile:~-3%" == ".ml" (
  call ocamlopt "%srcfile%" -o "%srcfile:~0,-3%.exe"
  del %srcfile:~0,-3%.cmx 2> nul
  del %srcfile:~0,-3%.cmi 2> nul
  del %srcfile:~0,-3%.obj 2> nul
  exit /b
)
if /i "%srcfile:~-3%" == ".py" (
  exit /b
)
if /i "%srcfile:~-4%" == ".cmd" (
  exit /b
)
if /i "%srcfile:~-4%" == ".exe" (
  exit /b
)
if [%3] == [quiet] (
  rem Do not complain
) else (
  echo Cannot make %srcfile%. Unsupported type.
)
exit /b 1

:append_cp
  set cp=%cp%;%1
exit /b


rem --------------------------------- TIME ---------------------------------

:time

set srcfile=interact
call :expand_sub
set iwrapper=%~dp0..\%bindir%\coact.exe
set set_interactive=
if exist %srcfile% (
  if exist %iwrapper% (
    call :command_sub
    set set_interactive=YES
  ) else (
    echo CANNOT RUN INTERACTIVE PROBLEM WITHOUT "coact.exe" WRAPPER
    exit /b 1
  )
)

if [%set_interactive%] == [YES] (
  set interactive=%iwrapper% 2000 67108864 =%command%=
) else (
  set interactive=
)

set wrapper=%~dp0..\%bindir%\run.exe
if exist %wrapper% (
  set wrapper=%wrapper% -1 -q -x -t 20s -y 5% -s run.dat -Xacp -o t-run.out -e t-run.err
) else (
  set wrapper=
)
goto run_main

rem --------------------------------- RUN ---------------------------------

:run
set wrapper=
set interactive=

:run_main

call :load_problem_properties
if [%2] == [*] (
    set srcfile=%problem.solution%
) else (
    set srcfile=%2
)

call :expand_sub

rem Build actual arguments list
shift
shift
set cmdargs=
:run_cmdargs_loop
if "%1" == "" goto run_cmdargs_done
set cmdargs=%cmdargs% %1
shift
goto run_cmdargs_loop
:run_cmdargs_done

call :command_sub
if errorlevel 1 exit /b 1

echo --- %wrapper% %interactive% %command% %cmdargs% >> t-run.log

%wrapper% %interactive% %command% %cmdargs%

call :copy_to_log_sub t-run.out
call :copy_to_log_sub t-run.err

exit /b

:copy_to_log_sub

if exist %1 (
  type %1 >> t-run.log
  del %1
)
exit /b

:command_sub

if /i "%srcfile%" == "Tests.java" (
  set cp="tests.jar"
  if exist lib (
    pushd lib
    for %%i in (*.jar) do (
      call :append_cp lib\%%i
    )
    popd
  )
)
if /i "%srcfile%" == "Tests.java" (
  set command=java -Xmx256m -Xss64m -cp "%cp%" -ea Tests
  exit /b
)
if /i "%srcfile%" == "Check.java" (
  set command=java -Xmx256m -Xss64m -cp "check.jar;%~dp0..\testlib\testlib4j.jar" -ea ru.ifmo.testlib.CheckerFramework Check
  exit /b
)
if /i "%srcfile%" == "Interact.java" (
  set command=java -Xmx256m -Xss64m -cp "interact.jar" -ea Interact
  exit /b
)
if /i "%srcfile:~-5%" == ".java" (
  set command=java -Xmx256m -Xss64m -cp "." -ea %srcfile:~0,-5%
  exit /b
)
if /i "%srcfile:~-4%" == ".dpr" (
  set command=%srcfile:~0,-4%.exe
  exit /b
)
if /i "%srcfile:~-4%" == ".class" (
  set command=java -Xmx256m -Xss64m -cp ".;%~dp0..\..\testlib" -ea %srcfile:~0,-4%
  exit /b
)
if /i "%srcfile:~-4%" == ".cpp" (
  set command=%srcfile:~0,-4%.exe
  exit /b
)
if /i "%srcfile:~-2%" == ".c" (
  set command=%srcfile:~0,-2%.exe
  exit /b
)
if /i "%srcfile:~-3%" == ".hs" (
  set command=%srcfile:~0,-3%.exe
  exit /b
)
if /i "%srcfile:~-3%" == ".ml" (
  set command="%srcfile:~0,-3%.exe"
  exit /b
)
if /i "%srcfile:~-3%" == ".py" (
  set command=python %srcfile%
  exit /b
)
if /i "%srcfile:~-4%" == ".cmd" (
  set command=%srcfile%
  exit /b
)
if /i "%srcfile:~-4%" == ".exe" (
  set command=%srcfile%
  exit /b
)
echo Cannot run %srcfile%. Unsupported type.
exit /b 1

rem ---------------------------- COMMON SUBROUTINES -----------------------

:rec_sub
rem Recursively repeats the same command in all subdirectories
for /d %%d in (*) do if /i "%%d" neq "tests" if /i "%%d" neq ".svn" if /i "%%d" neq "CVS" if /i "%%d" neq "__pcms" (
  pushd %%d
  call %~f0 %*
  popd
)
exit /b

:resolve_solution_sub
rem Resolves specified shortcut for solution into actual file

if exist "%srcfile%" (
  rem exitisting file was specified -- nothing more to do
  exit /b
)
if "%srcfile%" == "" (
  rem Just try problem name for solution name if none was specified
  set srcfile=%problem.source%
) else (
  rem Append suffix to problem name in attempt to find solution name
  set srcfile=%problem.source%_%srcfile%
)
rem !!! Now falls to expand_sub in order to find an appropriate extension for solution
:expand_sub
call :expand %srcfile%
set srcfile=%result%
exit /b

:expand
rem Usage "call :expand <file>" returns expaned file name in "result"
rem Expands <file> by checking various extensions in order: .java, .dpr, .cpp, .c, .hs, .ml, .py, .cmd, .exe
set result=%1
if exist %result% exit /b
for %%i in (java dpr cpp c hs ml py cmd exe) do if exist %result%.%%i (
  set result=%result%.%%i
  exit /b
)
exit /b

:testlogerror
rem Usage "call :testlogerror <action> <test>"
call :testlog %1 %2 Failed to run with exitcode %ERRORLEVEL%
exit /b

:testlog
rem Usage "call :testlog <action> <test> <message>"
set action=%1
set test=%2
shift
shift
set message=%1
shift
:testlog_message_loop
if "%1" == "" goto testlog_message_done
set message=%message% %1
shift
goto testlog_message_loop
:testlog_message_done

echo %message% on problem %problem.id% test %test%.
echo %test% %message% >> t-%action%.log
exit /b

:load_problem_properties
rem Loads "problem.properties" file
set problem.id=%problem%
set problem.name=
set problem.input=
set problem.output=
set problem.log=
set problem.solution=
set problem.source=
set problem.alias=
set problem.short-id=
set problem.timelimit=%contest.timelimit%
set problem.memorylimit=%contest.memorylimit%

call :load_properties problem.properties problem
if "%problem.solution%" == "" (
    set problem.solution=[???solution???]
)
if "%problem.input%" == "" (
    set problem.input=%problem.id%.in
)
if "%problem.output%" == "" (
    set problem.output=%problem.id%.out
)
if "%problem.log%" == "" (
    set problem.log=%problem.id%.log
)
if "%problem.source%" == "" (
    set problem.source=%problem.id%
)
if "%problem.checker%" == "" (
    set problem.checker=%problem.testset%
)
if "%problem.alias%" == "" (
    call :upcase %problem.id:~0,1%
    set problem.alias=!upcase.result!
)
if "%problem.short-id%" == "" (
    set problem.short-id=%problem.id:~0,1%
)
:problem_alias
exit /b

:load_contest_properties
rem Loads "..\contest.properties" file
if "%1" == "" (
    set load_contest_properties.location=..\contest.properties
) else (
    set load_contest_properties.location=%1
)
if "%2" == "" (
    set load_contest_properties.prefix=contest
) else (
    set load_contest_properties.prefix=%2
)

set contest.name-1=
set contest.name-2=
set contest.location=
set contest.date=
set contest.timelimit=2s
set contest.memorylimit=67108864

call :load_properties %load_contest_properties.location% %load_contest_properties.prefix%

set load_contest_properties.location=
set load_contest_properties.prefix=

exit /b

:load_properties
if exist %1 (
    for /F "tokens=1,* delims== " %%i in (%1) do (
        set %2.%%i=%%j
    )
)
exit /b

:update
rem Usage call :update variable-name variable-name
echo set %1=%%%2%% > %temp%\t.tmp.cmd
call %temp%\t.tmp.cmd
del %temp%\t.tmp.cmd

exit /b

:prepend
rem Usage call :prepend separator variable-name variable-name
rem echo :prepend %*
(
    echo if "%%%2%%" == "" ^(
        echo set %2=%%%3%%
    echo ^) else ^(
        echo set %2=%%%3%%%~1%%%2%%
    echo ^)
) > %temp%\t.tmp.cmd
call %temp%\t.tmp.cmd
del %temp%\t.tmp.cmd
exit /b

:expand_jurors
rem Usage call :expand_jurors variable-name jurors
set expand_jurors.variable=%1
set expand_jurors.first=%2
shift
shift

if "%expand_jurors.first%" == "" (
    set %expand_jurors.variable%=
) else (
    call :expand_jurors %expand_jurors.variable% %1 %2 %3 %4 %5 %6 %7 %8 %9
    call :prepend ", " %expand_jurors.variable% contest.juror.%expand_jurors.first%
)
exit /b

:substring_after
set substring_after.string=%~1
set substring_after.char=%~2
set substring_after.result=%~1

if "%substring_after.string:~1,1%" == "%substring_after.char%" (
    set substring_after.result=%substring_after.string:~2%
) else if "%substring_after.string:~2,1%" == "%substring_after.char%" (
    set substring_after.result=%substring_after.string:~3%
) else if "%substring_after.string:~3,1%" == "%substring_after.char%" (
    set substring_after.result=%substring_after.string:~4%
) else if "%substring_after.string:~4,1%" == "%substring_after.char%" (
    set substring_after.result=%substring_after.string:~5%
) else if "%substring_after.string:~5,1%" == "%substring_after.char%" (
    set substring_after.result=%substring_after.string:~6%
) else if "%substring_after.string:~6,1%" == "%substring_after.char%" (
    set substring_after.result=%substring_after.string:~7%
) else if "%substring_after.string:~7,1%" == "%substring_after.char%" (
    set substring_after.result=%substring_after.string:~8%
) else if "%substring_after.string:~8,1%" == "%substring_after.char%" (
    set substring_after.result=%substring_after.string:~9%
) else if "%substring_after.string:~9,1%" == "%substring_after.char%" (
    set substring_after.result=%substring_after.string:~10%
) else if "%substring_after.string:~10,1%" == "%substring_after.char%" (
    set substring_after.result=%substring_after.string:~11%
) else if "%substring_after.string:~11,1%" == "%substring_after.char%" (
    set substring_after.result=%substring_after.string:~12%
) else if "%substring_after.string:~12,1%" == "%substring_after.char%" (
    set substring_after.result=%substring_after.string:~13%
) else if "%substring_after.string:~13,1%" == "%substring_after.char%" (
    set substring_after.result=%substring_after.string:~14%
) else if "%substring_after.string:~14,1%" == "%substring_after.char%" (
    set substring_after.result=%substring_after.string:~15%
) else if "%substring_after.string:~15,1%" == "%substring_after.char%" (
    set substring_after.result=%substring_after.string:~16%
)
set substring_after.string=%1
set substring_after.char=%2

exit /b

:substring_before
set substring_before.string=%~1
set substring_before.char=%~2
set substring_before.result=%~1

if "%substring_before.string:~1,1%" == "%substring_before.char%" (
    set substring_before.result=%substring_before.string:~0,1%
) else if "%substring_before.string:~2,1%" == "%substring_before.char%" (
    set substring_before.result=%substring_before.string:~0,2%
) else if "%substring_before.string:~3,1%" == "%substring_before.char%" (
    set substring_before.result=%substring_before.string:~0,3%
) else if "%substring_before.string:~4,1%" == "%substring_before.char%" (
    set substring_before.result=%substring_before.string:~0,4%
) else if "%substring_before.string:~5,1%" == "%substring_before.char%" (
    set substring_before.result=%substring_before.string:~0,5%
) else if "%substring_before.string:~6,1%" == "%substring_before.char%" (
    set substring_before.result=%substring_before.string:~0,6%
) else if "%substring_before.string:~7,1%" == "%substring_before.char%" (
    set substring_before.result=%substring_before.string:~0,7%
) else if "%substring_before.string:~8,1%" == "%substring_before.char%" (
    set substring_before.result=%substring_before.string:~0,8%
) else if "%substring_before.string:~9,1%" == "%substring_before.char%" (
    set substring_before.result=%substring_before.string:~0,9%
) else if "%substring_before.string:~10,1%" == "%substring_before.char%" (
    set substring_before.result=%substring_before.string:~0,10%
) else if "%substring_before.string:~11,1%" == "%substring_before.char%" (
    set substring_before.result=%substring_before.string:~0,11%
) else if "%substring_before.string:~12,1%" == "%substring_before.char%" (
    set substring_before.result=%substring_before.string:~0,12%
) else if "%substring_before.string:~13,1%" == "%substring_before.char%" (
    set substring_before.result=%substring_before.string:~0,13%
) else if "%substring_before.string:~14,1%" == "%substring_before.char%" (
    set substring_before.result=%substring_before.string:~0,14%
) else if "%substring_before.string:~15,1%" == "%substring_before.char%" (
    set substring_before.result=%substring_before.string:~0,15%
)
set substring_before.string=%1
set substring_before.char=%2

exit /b

:upcase
set upcase.result=%~1
set upcase.result=%upcase.result:a=A%
set upcase.result=%upcase.result:b=B%
set upcase.result=%upcase.result:c=C%
set upcase.result=%upcase.result:d=D%
set upcase.result=%upcase.result:e=E%
set upcase.result=%upcase.result:f=F%
set upcase.result=%upcase.result:g=G%
set upcase.result=%upcase.result:h=H%
set upcase.result=%upcase.result:i=I%
set upcase.result=%upcase.result:j=J%
set upcase.result=%upcase.result:k=K%
set upcase.result=%upcase.result:l=L%
set upcase.result=%upcase.result:m=M%
set upcase.result=%upcase.result:n=N%
set upcase.result=%upcase.result:o=O%
set upcase.result=%upcase.result:p=P%
set upcase.result=%upcase.result:q=Q%
set upcase.result=%upcase.result:r=R%
set upcase.result=%upcase.result:s=S%
set upcase.result=%upcase.result:t=T%
set upcase.result=%upcase.result:u=U%
set upcase.result=%upcase.result:v=V%
set upcase.result=%upcase.result:w=W%
set upcase.result=%upcase.result:x=X%
set upcase.result=%upcase.result:y=Y%
set upcase.result=%upcase.result:z=Z%

:terminate
