set(BEGIN_EXAMPLE_REGEX "////[ ]*BEGIN-EXAMPLE")
set(END_EXAMPLE_REGEX "////[ ]*END-EXAMPLE")
set(PAUSE_EXAMPLE_REGEX "////[ ]*PAUSE-EXAMPLE[ ]*$")
set(RESUME_EXAMPLE_REGEX "////[ ]*RESUME-EXAMPLE[ ]*$")
set(LABEL_REGEX "////[ ]*LABEL")

function(extract_from_file extracted_files_var src_file output_dir)
  set(extracted_files)

  file(STRINGS ${src_file} src_lines)

  set(active_files)
  set(example_paused OFF)

  foreach(line IN LISTS src_lines)
    if("${line}" MATCHES "////")
      if("${line}" MATCHES "${BEGIN_EXAMPLE_REGEX}")
        string(REGEX MATCH "[^ ]+[ ]*$" out_name "${line}")
        message(STATUS "Generating ${out_name}")
        list(APPEND active_files ${out_name})
        # Remove files to begin appending.
        file(REMOVE ${output_dir}/listing_${out_name})
        list(APPEND extracted_files ${output_dir}/listing_${out_name})
      elseif("${line}" MATCHES "${END_EXAMPLE_REGEX}")
        string(REGEX MATCH "[^ ]+[ ]*$" out_name "${line}")
        list(FIND active_files "${out_name}" out_index)
        if(${out_index} LESS 0)
          message(WARNING "Name mismatch extracting from ${src_file}. ${out_name} never started.")
        else()
          list(REMOVE_AT active_files ${out_index})
        endif()
      elseif("${line}" MATCHES "${PAUSE_EXAMPLE_REGEX}")
        if(example_paused)
          message(WARNING "Badly nested pause/resume pair in ${src_file}.")
        else()
          set(example_paused ON)
        endif()
      elseif("${line}" MATCHES "${RESUME_EXAMPLE_REGEX}")
        if(example_paused)
          set(example_paused OFF)
        else()
          message(WARNING "Badly nested pause/resume pair in ${src_file}.")
        endif()
      elseif("${line}" MATCHES "${LABEL_REGEX}")
        string(REGEX MATCH "[^ ]+[ ]*$" label_name "${line}")
        foreach(file IN LISTS active_files)
          file(APPEND ${output_dir}/listing_${file} "@\\label{ex:${file}:${label_name}}@")
        endforeach()
      endif()
    else()
      if(NOT example_paused)
        foreach(file IN LISTS active_files)
          file(APPEND ${output_dir}/listing_${file} "${line}\n")
        endforeach()
      endif()
    endif()
  endforeach()

  foreach(unended_file IN LISTS active_files)
    message(WARNING "Out file ${unended_file} from ${src_file} started but never ended.")
  endforeach()

  if(example_paused)
    message(WARNING "Paused capture in ${src_file} never resumed.")
  endif()

  set(${extracted_files_var} ${extracted_files})
endfunction(extract_from_file)

# function(extract_examples created_files_var)
#   set(created_files)
#
#   foreach(src_file ${ARGN})
#     extract_from_file(extracted_files ${src_file})
#     list(APPEND created_files ${extracted_files})
#   endforeach()
#
#   set(${created_files_var} ${created_files} PARENT_SCOPE)
# endfunction(extract_examples)

# Originally these functions were used during configuration by including this
# script. Now these are called during the build and we use this code to set
# them up.
function(usage message)
  message(FATAL_ERROR "${message}
 USAGE:
 ${CMAKE_COMMAND} \\
   -D INPUT_FILE=<input> \\
   -D OUTPUT_DIRECTORY=<out_dir> \\
   -P ${CMAKE_CURRENT_LIST_FILE}
")
endfunction(usage)

if(NOT EXISTS ${INPUT_FILE})
  usage("Could not find input file '${INPUT_FILE}'")
endif()

if(IS_DIRECTORY ${INPUT_FILE})
  usage("'${INPUT_FILE}' is not a regular file")
endif()

if(NOT IS_DIRECTORY ${OUTPUT_DIRECTORY})
  usage("Output directory '${OUTPUT_DIRECTORY}' does not exist.")
endif()

extract_from_file(extracted_files ${INPUT_FILE} ${OUTPUT_DIRECTORY})
