/*----------------------------------------------------------------------------*/
/* include file                                                               */
/*----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif

#include "count_cmn.h"
#include "file_cmn.h"

/*----------------------------------------------------------------------------*/
/* define                                                                     */
/*----------------------------------------------------------------------------*/
#define FILE_SEPALATE '/'

/*----------------------------------------------------------------------------*/
/* structure definition                                                       */
/*----------------------------------------------------------------------------*/
typedef struct tag_FileTree {
    struct tag_FileTree* next;
    char* fname;
}
_FileTree;

/*----------------------------------------------------------------------------*/
/* global variable declaration                                                */
/*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/* static variable declaration                                                */
/*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/* static function declaration                                                */
/*----------------------------------------------------------------------------*/
static int getDir(const char* dirname, int *pifilenum, _FileTree **ppftree);

/*----------------------------------------------------------------------------*/
/* global function                                                            */
/*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/* file path                                                                  */
/*----------------------------------------------------------------------------*/
/*パス名からディレクトリ名とファイル名を取得する*/
void getDirFileName(const char *pcpath, char *pcdir, char *pcfile) {
    char *p;
    int iLenDir;

    if(isDir(pcpath)) {
        /*ファイル名が含まれていない*/
        strcpy(pcdir, pcpath);
        pcdir[strlen(pcpath)] = '\0';
        pcfile = '\0';

    } else {

        /*ファイルパス末尾からFILE_SEPALATEを検索*/
        p= strrchr(pcpath, FILE_SEPALATE);

        if (p == NULL) {        /* '/' がない */
            *pcdir = '\0';
            strncpy(pcfile, pcpath, FILE_NAME_SIZE);
        } else if (p == pcpath) {   /* '/' が先頭だけ */
            *pcdir = FILE_SEPALATE;
            strncpy(pcfile, p + 1 , FILE_NAME_SIZE);
        } else {                  /* '/' が見つかった */
            iLenDir = p - pcpath;
            if(iLenDir > FILE_NAME_SIZE) {
                iLenDir = FILE_NAME_SIZE;
            }
            memcpy(pcdir, pcpath, iLenDir);
            pcdir[iLenDir] = '\0';
            strncpy(pcfile, p + 1, FILE_NAME_SIZE);
        }
    }

    return;
}

/*ディレクトリとファイル名を結合*/
void setDirFileName(const char *pcdir, const char *pcfile, char *pcpath) {
    char *p;

    p = pcpath;
    strncpy(p, pcdir, FILE_NAME_SIZE);
    p += strlen(pcdir);
    *p = FILE_SEPALATE;
    p++;
    strncpy(p, pcfile, FILE_NAME_SIZE);
    p += strlen(pcfile);
    *p = '\0';

    return;
}

int getAbsolutePath(const char *pcfile, char *pcpath) 
{
    int iRet;

    iRet = RET_NG;

    if(pcfile == NULL || pcpath == NULL) {
        goto FUNC_END;
    }

    //TODO

    iRet = RET_OK;

FUNC_END:
    return iRet;
}


/*----------------------------------------------------------------------------*/
/* directory                                                                  */
/*----------------------------------------------------------------------------*/

int isDir(const char* pcdir) {
    int iRet;

    iRet = RET_FALSE;

    //TODO

    iRet = RET_TRUE;

    return iRet;
}


/*指定ディレクトリ以下のファイル一覧を取得*/
int getFileList(const char *pcdir, _FileList **ppflist) {
    _FileList *pfiles;      /*ファイル一覧*/
    _FileTree tree_first;        /*ファイルツリー開始位置*/
    _FileTree* pftree;      /*ファイルツリーポインタ*/
    int iFileNum;           /*ファイル数*/
    int iRet;
    int i;

    iRet = RET_NG;
    tree_first.next = NULL;
    pftree = &tree_first;
    
    *ppflist = NULL;
    iFileNum = 0;

    /*ディレクトリ検索*/
    iRet = getDir(pcdir, &iFileNum, &pftree);
    if(iRet != RET_OK) {
        /*メモリ確保の途中で失敗している場合を考慮する必要あり。開放漏れ*/
        goto FUNC_END;
    }

    /*ファイル一覧作成*/
    pfiles = (_FileList*)malloc(sizeof(_FileList) + (iFileNum - 1) * sizeof (char*));
    if(pfiles == NULL){
        goto FUNC_END;
    }
        
    pfiles->count = iFileNum;
    pftree = tree_first.next;
    for (i = 0; i < iFileNum; i++) {
        pfiles->filename[i] = pftree->fname;
        printf("filename[%d] = %s\n", i, pftree->fname);//TODO
        pftree = pftree->next;
    }
    /*メモリ開放していく*/
    for (pftree = tree_first.next; pftree != NULL; pftree = tree_first.next) {
        tree_first.next = pftree->next;
        free(pftree);
    }
    iRet = RET_OK;
    *ppflist = pfiles;

FUNC_END:

    
    return iRet;
}

void freeFileList(_FileList *pflist) {
    if (pflist == NULL) {
        return;
    }

    while (pflist->count--) {
        free(pflist->filename[pflist->count]);
    }
    free(pflist);
    pflist = NULL;
}

/*ディレクトリ内のファイル情報取得*/
static int getDir(const char* dirname, int *pifilenum, _FileTree **ppftree)
{
    int iRet;

    iRet = RET_NG;
    *ppftree = NULL;

    //TODO

    return iRet;
}
