# Check that file contains line that matches regular expression.
# Sets IS_FOUND variable to TRUE if found and to FALSE otherwise.
macro(check_line_exists TARGET_FILE REG_EXP_REF)
  set(IS_FOUND "FALSE")

  file(STRINGS ${TARGET_FILE} FOUND_LINE LIMIT_COUNT 1 REGEX "${${REG_EXP_REF}}")
  list(LENGTH FOUND_LINE _VAR_LEN)

  if(_VAR_LEN GREATER 0)
    set(IS_FOUND "TRUE")
  endif()
endmacro()

# Search and parse project section line by project name.
# If search was successful stores found type and guid into FOUND_TYPE and FOUND_GUID variables respectively.
# Sets IS_FOUND variable to TRUE if found and to FALSE otherwise.
macro(parse_project_section TARGET_FILE PROJECT_NAME)
  set(REG_EXP "^Project\\(\\\"{(.+)}\\\"\\) = \\\"${PROJECT_NAME}\\\", \\\".+\\..+\\\", \\\"{(.+)}\\\"$")

  check_line_exists(${TARGET_FILE} REG_EXP)
  if(NOT IS_FOUND)
    return()
  endif()

  string(REGEX REPLACE "${REG_EXP}" "\\1;\\2" _GUIDS "${FOUND_LINE}")

  list(GET _GUIDS 0 FOUND_TYPE)
  list(GET _GUIDS 1 FOUND_GUID)
endmacro()

# Search project section line by project name and type.
# Returns TRUE if found and FALSE otherwise
function(check_project_type TARGET_FILE PROJECT_NAME PROJECT_TYPE RESULT)
  set(${RESULT} "FALSE" PARENT_SCOPE)

  parse_project_section(${TARGET_FILE} ${PROJECT_NAME})
  if(IS_FOUND AND FOUND_TYPE STREQUAL PROJECT_TYPE)
    set(${RESULT} "TRUE" PARENT_SCOPE)
  endif()
endfunction()


# Search project section line by project name and id.
# Returns TRUE if found and FALSE otherwise
function(check_project_guid TARGET_FILE PROJECT_NAME PROJECT_GUID RESULT)
  set(${RESULT} "FALSE" PARENT_SCOPE)

  parse_project_section(${TARGET_FILE} ${PROJECT_NAME})
  if(IS_FOUND AND FOUND_GUID STREQUAL PROJECT_GUID)
    set(${RESULT} "TRUE" PARENT_SCOPE)
  endif()
endfunction()


# Search project's build configuration line by project name and target platform name.
# Returns TRUE if found and FALSE otherwise
function(check_custom_platform TARGET_FILE PROJECT_NAME PLATFORM_NAME RESULT)
  set(${RESULT} "FALSE" PARENT_SCOPE)

  # extract project guid
  parse_project_section(${TARGET_FILE} ${PROJECT_NAME})
  if(NOT IS_FOUND)
    return()
  endif()

  # probably would be better to use configuration name
  # extracted from CMAKE_CONFIGURATION_TYPES than just hardcoded "Debug" instead
  set(REG_EXP "^(\t)*\\{${FOUND_GUID}\\}\\.Debug[^ ]*\\.ActiveCfg = Debug\\|${PLATFORM_NAME}$")
  check_line_exists(${TARGET_FILE} REG_EXP)

  set(${RESULT} ${IS_FOUND} PARENT_SCOPE)
endfunction()

# Search project's build configuration line by project name and target configuration name.
# Returns TRUE if found and FALSE otherwise
function(check_custom_configuration TARGET_FILE PROJECT_NAME SLN_CONFIG DST_CONFIG RESULT)
  set(${RESULT} "FALSE" PARENT_SCOPE)
  # extract project guid
  parse_project_section(${TARGET_FILE} ${PROJECT_NAME})
  if(NOT IS_FOUND)
    return()
  endif()

  set(REG_EXP "^(\t)*\\{${FOUND_GUID}\\}\\.${SLN_CONFIG}[^ ]*\\.ActiveCfg = ${DST_CONFIG}\\|.*$")
  check_line_exists(${TARGET_FILE} REG_EXP)

  set(${RESULT} ${IS_FOUND} PARENT_SCOPE)
endfunction()

# RunCMake test check helper
function(check_project test name guid type platform imported_release_config_name)
  set(sln "${RunCMake_TEST_BINARY_DIR}/${test}.sln")
  set(sep "")
  set(failed "")
  if(NOT type)
    set(type 8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942)
  endif()
  if(NOT platform)
    if(RunCMake_GENERATOR_PLATFORM)
      set(platform "${RunCMake_GENERATOR_PLATFORM}")
    elseif("${RunCMake_GENERATOR}" MATCHES "Win64")
      set(platform "x64")
    elseif(VS_PLATFORM_NAME)
      set(platform "${VS_PLATFORM_NAME}")
    else()
      set(platform "Win32")
    endif()
  endif()
  if(NOT imported_release_config_name)
    set(imported_release_config_name "Release")
  endif()
  if(guid)
    check_project_guid("${sln}" "${name}" "${guid}" passed_guid)
    if(NOT passed_guid)
      string(APPEND failed "${sep}${name} solution has no project with expected GUID=${guid}")
      set(sep "\n")
    endif()
  else()
    set(passed_guid 1)
  endif()
  check_project_type("${sln}" "${name}" "${type}" passed_type)
  if(NOT passed_type)
    string(APPEND failed "${sep}${name} solution has no project with expected TYPE=${type}")
    set(sep "\n")
  endif()
  check_custom_platform("${sln}" "${name}" "${platform}" passed_platform)
  if(NOT passed_platform)
    string(APPEND failed "${sep}${name} solution has no project with expected PLATFORM=${platform}")
    set(sep "\n")
  endif()
  check_custom_configuration("${sln}" "${name}" "Release" "${imported_release_config_name}" passed_configuration)
  if(NOT passed_configuration)
    string(APPEND failed "${sep}${name} solution has no project with expected CONFIG=${imported_release_config_name}")
    set(sep "\n")
  endif()

  set(RunCMake_TEST_FAILED "${failed}" PARENT_SCOPE)
endfunction()
