/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <axutil_dir_handler.h>
#include <axutil_file.h>
#include <platforms/axutil_platform_auto_sense.h>
#include <axutil_string.h>
#ifndef S_ISDIR
#   define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
#endif

#ifdef AXIS2_ARCHIVE_ENABLED
#include <minizip/axis2_archive_extract.h>
#endif


extern int AXIS2_ALPHASORT(
    );
#ifdef IS_MACOSX
int dir_select(
    struct dirent *entry);
int file_select(
    struct dirent *entry);
#else
int dir_select(
    const struct dirent *entry);
int file_select(
    const struct dirent *entry);
#endif

/**
 * List the dll files in the given service or module folder path
 * @param pathname path to your service or module directory
 * @return array list of dll file names
 */
AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
axutil_dir_handler_list_services_or_modules_in_dir(
    const axutil_env_t *env,
    const axis2_char_t *pathname)
{
    axutil_array_list_t *file_list = NULL;
    struct stat *buf = NULL;
    int count = 1;
    int i = 0;
    struct dirent **files = NULL;
    /*int file_select(
     );*/
    /* Removed un-wanted redefinition leading to warnings on
     * Windows. If this is the desired behaviour, please look
     * into the file_select function definition below and comment
     * out the code if neccessary.
     */
    axis2_status_t status = AXIS2_FAILURE;

    AXIS2_ENV_CHECK(env, NULL);
    file_list = axutil_array_list_create(env, 100);
    count = AXIS2_SCANDIR(pathname, &files, file_select, AXIS2_ALPHASORT);
    /* If no files found, make a non-selectable menu item */
    if(count <= 0)
    {
        axutil_array_list_free(file_list, env);
        AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "No files in the path %s.", pathname);
        return NULL;
    }

    for(i = 1; i < (count + 1); ++i)
    {
        axis2_char_t *fname = NULL;
        axutil_file_t *arch_file = NULL;
        axis2_char_t *path = NULL;
        axis2_char_t *temp_path = NULL;

        fname = files[i - 1]->d_name;
        arch_file = (axutil_file_t *)axutil_file_create(env);
        if(!arch_file)
        {
            int size = 0;
            int j = 0;
            axutil_file_t *del_file = NULL;

            size = axutil_array_list_size(file_list, env);
            for(j = 0; j < size; j++)
            {
                del_file = axutil_array_list_get(file_list, env, j);
                axutil_file_free(del_file, env);
            }
            axutil_array_list_free(file_list, env);
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return NULL;
        }
        axutil_file_set_name(arch_file, env, fname);
        temp_path = axutil_stracat(env, pathname, AXIS2_PATH_SEP_STR);
        path = axutil_stracat(env, temp_path, fname);
        AXIS2_FREE(env->allocator, temp_path);
        if(!path)
        {
            int size = 0;
            int j = 0;
            axutil_file_t *del_file = NULL;

            axutil_file_free(arch_file, env);
            size = axutil_array_list_size(file_list, env);
            for(j = 0; j < size; j++)
            {
                del_file = axutil_array_list_get(file_list, env, j);
                axutil_file_free(del_file, env);
            }
            axutil_array_list_free(file_list, env);
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return NULL;
        }
        axutil_file_set_path(arch_file, env, path);
        buf = AXIS2_MALLOC(env->allocator, sizeof(struct stat));
        if(!buf)
        {
            int size = 0;
            int j = 0;
            axutil_file_t *del_file = NULL;

            AXIS2_FREE(env->allocator, path);
            axutil_file_free(arch_file, env);
            size = axutil_array_list_size(file_list, env);
            for(j = 0; j < size; j++)
            {
                del_file = axutil_array_list_get(file_list, env, j);
                axutil_file_free(del_file, env);
            }
            axutil_array_list_free(file_list, env);
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return NULL;
        }
        stat(path, buf);
        axutil_file_set_timestamp(arch_file, env, (time_t)buf->st_ctime);
        status = axutil_array_list_add(file_list, env, arch_file);
        if(AXIS2_SUCCESS != status)
        {
            int size = 0;
            int j = 0;
            axutil_file_t *del_file = NULL;

            axutil_file_free(arch_file, env);
            AXIS2_FREE(env->allocator, path);
            AXIS2_FREE(env->allocator, buf);
            size = axutil_array_list_size(file_list, env);
            for(j = 0; j < size; j++)
            {
                del_file = axutil_array_list_get(file_list, env, j);
                axutil_file_free(del_file, env);
            }
            axutil_array_list_free(file_list, env);
            return NULL;
        }
        AXIS2_FREE(env->allocator, path);
        AXIS2_FREE(env->allocator, buf);

    }
    return file_list;
}

/**
 * List services or modules directories in the services or modules folder
 * respectively
 * @param pathname path  your modules or services folder
 * @return array list of contents of services or modules folder
 */
AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
axutil_dir_handler_list_service_or_module_dirs(
    const axutil_env_t *env,
    const axis2_char_t *pathname)
{
    axutil_array_list_t *file_list = NULL;
    struct stat *buf = NULL;
    int count = 1;
    int i = 0;
    struct dirent **files = NULL;
    char cwd[500];
    int chdir_result = 0;

    /**FIXME:
     * This magic number 500 was selected as a temporary solution. It has to be
     * replaced with dynamic memory allocation. This will be done once the use of
     * errno after getwcd() on Windows is figured out.
     */

    axis2_status_t status = AXIS2_FAILURE;

    if(!AXIS2_GETCWD(cwd, 500))
    {
        /* if we can't identify working directory, it will be a critical failure */
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot identify working directory");
        exit(1);
    }

    /* pathname is path of services directory or modules directory. */
    chdir_result = AXIS2_CHDIR(pathname);
    if(chdir_result == -1)
    {
        /* we could not be able to find the path given. However, this will not be a problem
         * because services and modules are optional.
         */
        AXIS2_LOG_INFO(env->log, "Cannot find path %s.", pathname);
        return NULL;
    }
#ifdef AXIS2_ARCHIVE_ENABLED
    axis2_archive_extract();
#endif

    count = AXIS2_SCANDIR(pathname, &files, dir_select, AXIS2_ALPHASORT);
    chdir_result = AXIS2_CHDIR(cwd);
    if(chdir_result == -1)
    {
        /* we are changing back to working directory. If we can't change, this will be critical*/
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot change directory to working directory");
        exit(1);
    }

    /* If no files found, make a non-selectable menu item */
    if(count <= 0)
    {
        AXIS2_LOG_INFO(env->log, "No files in the path %s.", pathname);
        return NULL;
    }

    file_list = axutil_array_list_create(env, 0);
    if(!file_list)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create file list.");
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    for(i = 1; i < (count + 1); ++i)
    {
        axis2_char_t *fname = NULL;
        axutil_file_t *arch_file = NULL;
        axis2_char_t *path = NULL;
        axis2_char_t *temp_path = NULL;

        fname = files[i - 1]->d_name;
        arch_file = (axutil_file_t *)axutil_file_create(env);
        if(!arch_file)
        {
            int size = 0;
            int j = 0;
            axutil_file_t *del_file = NULL;

            size = axutil_array_list_size(file_list, env);
            for(j = 0; j < size; j++)
            {
                del_file = axutil_array_list_get(file_list, env, j);
                axutil_file_free(del_file, env);
            }
            axutil_array_list_free(file_list, env);
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return NULL;
        }
        axutil_file_set_name(arch_file, env, fname);
        temp_path = axutil_stracat(env, pathname, AXIS2_PATH_SEP_STR);
        path = axutil_stracat(env, temp_path, fname);
        if(!path)
        {
            int size = 0;
            int j = 0;
            axutil_file_t *del_file = NULL;

            axutil_file_free(arch_file, env);
            size = axutil_array_list_size(file_list, env);
            for(j = 0; j < size; j++)
            {
                del_file = axutil_array_list_get(file_list, env, j);
                axutil_file_free(del_file, env);
            }
            axutil_array_list_free(file_list, env);
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return NULL;
        }
        axutil_file_set_path(arch_file, env, path);
        AXIS2_FREE(env->allocator, temp_path);
        buf = AXIS2_MALLOC(env->allocator, sizeof(struct stat));
        if(!buf)
        {
            int size = 0;
            int j = 0;
            axutil_file_t *del_file = NULL;

            axutil_file_free(arch_file, env);
            AXIS2_FREE(env->allocator, path);
            size = axutil_array_list_size(file_list, env);
            for(j = 0; j < size; j++)
            {
                del_file = axutil_array_list_get(file_list, env, j);
                axutil_file_free(del_file, env);
            }
            axutil_array_list_free(file_list, env);
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return NULL;
        }
        stat(path, buf);
        axutil_file_set_timestamp(arch_file, env, (time_t)buf->st_ctime);
        status = axutil_array_list_add(file_list, env, arch_file);
        if(AXIS2_SUCCESS != status)
        {
            int size = 0;
            int j = 0;
            axutil_file_t *del_file = NULL;

            axutil_file_free(arch_file, env);
            AXIS2_FREE(env->allocator, path);
            AXIS2_FREE(env->allocator, buf);
            size = axutil_array_list_size(file_list, env);
            for(j = 0; j < size; j++)
            {
                del_file = axutil_array_list_get(file_list, env, j);
                axutil_file_free(del_file, env);
            }
            axutil_array_list_free(file_list, env);
            return NULL;
        }
        AXIS2_FREE(env->allocator, path);
        AXIS2_FREE(env->allocator, buf);
    }

    for(i = 0; i < count; i++)
    {
        free(files[i]);
    }
    free(files);
    return file_list;
}

#ifdef IS_MACOSX
    int file_select(struct dirent *entry)
{
#else
	int file_select(const struct dirent *entry)
{
#endif
    /** FIXME:
     * This block of code has been sitting here doing nothing.
     * I have made the existing logic use this code portion.
     * Have no idea about the side-effects of this modification.
     * If this code block is not required, we might as well remove
     * it.
     */
    axis2_char_t *ptr;

    if((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0))
        return (AXIS2_FALSE);

    /* Check for filename extensions */
    ptr = axutil_rindex(entry->d_name, '.');
    if((ptr) && ((strcmp(ptr, AXIS2_LIB_SUFFIX) == 0)))
    {
        return (AXIS2_TRUE);
    }
    else
        return (AXIS2_FALSE);
}

#ifdef IS_MACOSX
int
dir_select(
    struct dirent *entry)
#else
int
dir_select(
    const struct dirent *entry)
#endif
{
    struct stat stat_p;

    if(-1 == stat(entry->d_name, &stat_p))
        return (AXIS2_FALSE);

    if((entry->d_name[0] == '.') || (!S_ISDIR(stat_p.st_mode)))
    {
        return (AXIS2_FALSE);
    }

    return AXIS2_TRUE;
}
