#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char* INCLUDE_START = "<!-- include ";
const char* INCLUDE_END = " -->";

const char* urlList[] = {
  "/TEST.HTM",
  "/HOGE.HTM",
  NULL
};

char* htmlList[] = {
  "TESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTEST",
  "HOGEHOGEHOGEHOGEHOGEHOGEHOGE",
  NULL
};

char* searchHtml(const char* url) {
  for (int i = 0; urlList[i] != NULL; i++) {
    if (strcmp(url, urlList[i]) == 0) {
      return htmlList[i];
    }
  }
  return NULL;
}

int scan(char** source, int* bufferSize) {
  char* ptr = *source;
  char* includeStart = NULL;
  char fileName[256] = "";
  int contentLength = strlen(*source);
  
  // include文開始を探索
  while ((includeStart = strstr(ptr, INCLUDE_START)) != NULL) {
    // include文開始の終端から探索
    ptr = includeStart + strlen(INCLUDE_START);

    // include文の終了を探索
    char* includeEnd = strstr(ptr, INCLUDE_END);
    if (includeEnd == NULL) {
      break; // 終端が存在しない場合は正しいincludeでない、かつ以後include文は存在しないといえるため何もしない
    }

    // include対象を取得
    memset(fileName, 0, sizeof(fileName));
    memcpy(fileName, ptr, (includeEnd - ptr)); // 終端から始端の間にURLが入っている

    // 次回の探索はinclude文終了の終端から
    ptr = includeEnd + strlen(INCLUDE_END);

    // include文自体の文字列長を求めておく(終端 - 始端)
    int includeStatementLength = (ptr - includeStart);

    // include対象の文字列を取得
    char* includeFileData = searchHtml(fileName);

    if (includeFileData == NULL) {
      continue; // include対象が存在しない場合は
    }

    // 新しく確保すべきサイズ(元々の文字列長 - include文の文字列長 + include対象の文字列長 + 1)
    int newSize = contentLength - includeStatementLength + strlen(includeFileData) + 1;

    // バッファが足りない場合は伸長
    if (*bufferSize < newSize) {
      printf("bufferSize=%d, newSize=%d\n", *bufferSize, newSize);
      char* newBuffer = (char*)realloc(*source, newSize);
      if (newBuffer == NULL) {
        return -1; // 拡張失敗
      }
      *source = newBuffer;
      *bufferSize = newSize;
    }

    // include文をinclude対象の文字列に置換する
    int includeContentsLength = strlen(includeFileData);
    char* restContentsAddrDst = includeStart + includeContentsLength;
    char* restContentsAddrSrc = includeStart + includeStatementLength;
    int restContentsLength = strlen(restContentsAddrSrc);
    memmove(restContentsAddrDst, restContentsAddrSrc, restContentsLength); // include文の後に続く文字列をコピー
    restContentsAddrDst[restContentsLength] = '\0';
    memcpy(includeStart, includeFileData, includeContentsLength); // include対象の埋め込み
    contentLength = strlen(*source);
  }

  return 0;
}

int main() {
  char* str = "Hello <!-- include /TEST.HTM --> <!-- include /HOGE.HTM --> World!!";
  char* buffer = NULL;

  buffer = (char*)malloc(strlen(str) + 1);

  strcpy(buffer, str);


  int bufferSize = strlen(str) + 1;
  scan(&buffer, &bufferSize);
  printf("%s\n", buffer);

  free(buffer);
  return 0;
}