/*             ----> DO NOT REMOVE THE FOLLOWING NOTICE <----

                   Copyright (c) 2014-2015 Datalight, Inc.
                       All Rights Reserved Worldwide.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; use version 2 of the License.

    This program is distributed in the hope that it will be useful,
    but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty
    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*  Businesses and individuals that for commercial or other reasons cannot
    comply with the terms of the GPLv2 license may obtain a commercial license
    before incorporating Reliance Edge into proprietary software for
    distribution in any form.  Visit http://www.datalight.com/reliance-edge for
    more information.
*/
/** @file
    @brief Implements path utilities for the POSIX-like API layer.
*/
#include <redfs.h>

#if REDCONF_API_POSIX == 1

#include <redcoreapi.h>
#include <redvolume.h>
#include <redposix.h>
#include <redpath.h>


static bool IsRootDir(const char *pszLocalPath);
static bool PathHasMoreNames(const char *pszPathIdx);


/** @brief Split a path into its component parts: a volume and a volume-local
           path.

    @param pszPath          The path to split.
    @param pbVolNum         On successful return, if non-NULL, populated with
                            the volume number extracted from the path.
    @param ppszLocalPath    On successful return, populated with the
                            volume-local path: the path stripped of any volume
                            path prefixing.  If this parameter is NULL, that
                            indicates there should be no local path, and any
                            characters beyond the prefix (other than path
                            separators) are treated as an error.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EINVAL @p pszPath is `NULL`.
    @retval -RED_ENOENT @p pszPath could not be matched to any volume; or
                        @p ppszLocalPath is NULL but @p pszPath includes a local
                        path.
*/
REDSTATUS RedPathSplit(
    const char     *pszPath,
    uint8_t        *pbVolNum,
    const char    **ppszLocalPath)
{
    REDSTATUS       ret = 0;

    if(pszPath == NULL)
    {
        ret = -RED_EINVAL;
    }
    else
    {
        const char *pszLocalPath = pszPath;
        uint8_t     bMatchVol = UINT8_MAX;
        uint32_t    ulMatchLen = 0U;
        uint8_t     bDefaultVolNum = UINT8_MAX;
        uint8_t     bVolNum;

        for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++)
        {
            const char *pszPrefix = gaRedVolConf[bVolNum].pszPathPrefix;
            uint32_t    ulPrefixLen = RedStrLen(pszPrefix);

            if(ulPrefixLen == 0U)
            {
                /*  A volume with a path prefix of an empty string is the
                    default volume, used when the path does not match the
                    prefix of any other volume.

                    The default volume should only be found once.  During
                    initialization, RedCoreInit() ensures that all volume
                    prefixes are unique (including empty prefixes).
                */
                REDASSERT(bDefaultVolNum == UINT8_MAX);
                bDefaultVolNum = bVolNum;
            }
            /*  For a path to match, it must either be the prefix exactly, or
                be followed by a path separator character.  Thus, with a volume
                prefix of "/foo", both "/foo" and "/foo/bar" are matches, but
                "/foobar" is not.
            */
            else if(    (RedStrNCmp(pszPath, pszPrefix, ulPrefixLen) == 0)
                     && ((pszPath[ulPrefixLen] == '\0') || (pszPath[ulPrefixLen] == REDCONF_PATH_SEPARATOR)))
            {
                /*  The length of this match should never exactly equal the
                    length of a previous match: that would require a duplicate
                    volume name, which should have been detected during init.
                */
                REDASSERT(ulPrefixLen != ulMatchLen);

                /*  If multiple prefixes match, the longest takes precedence.
                    Thus, if there are two prefixes "Flash" and "Flash/Backup",
                    the path "Flash/Backup/" will not be erroneously matched
                    with the "Flash" volume.
                */
                if(ulPrefixLen > ulMatchLen)
                {
                    bMatchVol = bVolNum;
                    ulMatchLen = ulPrefixLen;
                }
            }
            else
            {
                /*  No match, keep looking.
                */
            }
        }

        if(bMatchVol != UINT8_MAX)
        {
            /*  The path matched a volume path prefix.
            */
            bVolNum = bMatchVol;
            pszLocalPath = &pszPath[ulMatchLen];
        }
        else if(bDefaultVolNum != UINT8_MAX)
        {
            /*  The path didn't match any of the prefixes, but one of the
                volumes has a path prefix of "", so an unprefixed path is
                assigned to that volume.
            */
            bVolNum = bDefaultVolNum;
            REDASSERT(pszLocalPath == pszPath);
        }
        else
        {
            /*  The path cannot be assigned a volume.
            */
            ret = -RED_ENOENT;
        }

        if(ret == 0)
        {
            if(pbVolNum != NULL)
            {
                *pbVolNum = bVolNum;
            }

            if(ppszLocalPath != NULL)
            {
                *ppszLocalPath = pszLocalPath;
            }
            else
            {
                /*  If no local path is expected, then the string should either
                    terminate after the path prefix or the local path should name
                    the root directory.  Allowing path separators here means that
                    red_mount("/data/") is OK with a path prefix of "/data".
                */
                if(pszLocalPath[0U] != '\0')
                {
                    if(!IsRootDir(pszLocalPath))
                    {
                        ret = -RED_ENOENT;
                    }
                }
            }
        }
    }

    return ret;
}


/** @brief Lookup the inode named by the given path.

    @param pszLocalPath The path to lookup; this is a local path, without any
                        volume prefix.
    @param pulInode     On successful return, populated with the number of the
                        inode named by @p pszLocalPath.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0                   Operation was successful.
    @retval -RED_EINVAL         @p pszLocalPath is `NULL`; or @p pulInode is
                                `NULL`.
    @retval -RED_EIO            A disk I/O error occurred.
    @retval -RED_ENOENT         @p pszLocalPath is an empty string; or
                                @p pszLocalPath does not name an existing file
                                or directory.
    @retval -RED_ENOTDIR        A component of the path other than the last is
                                not a directory.
    @retval -RED_ENAMETOOLONG   The length of a component of @p pszLocalPath is
                                longer than #REDCONF_NAME_MAX.
*/
REDSTATUS RedPathLookup(
    const char *pszLocalPath,
    uint32_t   *pulInode)
{
    REDSTATUS   ret;

    if((pszLocalPath == NULL) || (pulInode == NULL))
    {
        REDERROR();
        ret = -RED_EINVAL;
    }
    else if(pszLocalPath[0U] == '\0')
    {
        ret = -RED_ENOENT;
    }
    else if(IsRootDir(pszLocalPath))
    {
        ret = 0;
        *pulInode = INODE_ROOTDIR;
    }
    else
    {
        uint32_t    ulPInode;
        const char *pszName;

        ret = RedPathToName(pszLocalPath, &ulPInode, &pszName);

        if(ret == 0)
        {
            ret = RedCoreLookup(ulPInode, pszName, pulInode);
        }
    }

    return ret;
}


/** @brief Given a path, return the parent inode number and a pointer to the
           last component in the path (the name).

    @param pszLocalPath The path to examine; this is a local path, without any
                        volume prefix.
    @param pulPInode    On successful return, populated with the inode number of
                        the parent directory of the last component in the path.
                        For example, with the path "a/b/c", populated with the
                        inode number of "b".
    @param ppszName     On successful return, populated with a pointer to the
                        last component in the path.  For example, with the path
                        "a/b/c", populated with a pointer to "c".

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0                   Operation was successful.
    @retval -RED_EINVAL         @p pszLocalPath is `NULL`; or @p pulPInode is
                                `NULL`; or @p ppszName is `NULL`; or the path
                                names the root directory.
    @retval -RED_EIO            A disk I/O error occurred.
    @retval -RED_ENOENT         @p pszLocalPath is an empty string; or a
                                component of the path other than the last does
                                not exist.
    @retval -RED_ENOTDIR        A component of the path other than the last is
                                not a directory.
    @retval -RED_ENAMETOOLONG   The length of a component of @p pszLocalPath is
                                longer than #REDCONF_NAME_MAX.
*/
REDSTATUS RedPathToName(
    const char     *pszLocalPath,
    uint32_t       *pulPInode,
    const char    **ppszName)
{
    REDSTATUS       ret;

    if((pszLocalPath == NULL) || (pulPInode == NULL) || (ppszName == NULL))
    {
        REDERROR();
        ret = -RED_EINVAL;
    }
    else if(IsRootDir(pszLocalPath))
    {
        ret = -RED_EINVAL;
    }
    else if(pszLocalPath[0U] == '\0')
    {
        ret = -RED_ENOENT;
    }
    else
    {
        uint32_t ulInode = INODE_ROOTDIR;
        uint32_t ulPInode = INODE_INVALID;
        uint32_t ulPathIdx = 0U;
        uint32_t ulLastNameIdx = 0U;

        ret = 0;

        do
        {
            uint32_t ulNameLen;

            /*  Skip over path separators, to get pszLocalPath[ulPathIdx]
                pointing at the next name.
            */
            while(pszLocalPath[ulPathIdx] == REDCONF_PATH_SEPARATOR)
            {
                ulPathIdx++;
            }

            if(pszLocalPath[ulPathIdx] == '\0')
            {
                break;
            }

            /*  Point ulLastNameIdx at the first character of the name; after
                we exit the loop, it will point at the first character of the
                last name in the path.
            */
            ulLastNameIdx = ulPathIdx;

            /*  Point ulPInode at the parent inode: either the root inode
                (first pass) or the inode of the previous name.  After we exit
                the loop, this will point at the parent inode of the last name.
            */
            ulPInode = ulInode;

            ulNameLen = RedNameLen(&pszLocalPath[ulPathIdx]);

            /*  Lookup the inode of the name, unless we are at the last name in
                the path: we don't care whether the last name exists or not.
            */
            if(PathHasMoreNames(&pszLocalPath[ulPathIdx + ulNameLen]))
            {
                ret = RedCoreLookup(ulPInode, &pszLocalPath[ulPathIdx], &ulInode);
            }

            /*  Move on to the next path element.
            */
            if(ret == 0)
            {
                ulPathIdx += ulNameLen;
            }
        }
        while(ret == 0);

        if(ret == 0)
        {
            *pulPInode = ulPInode;
            *ppszName = &pszLocalPath[ulLastNameIdx];
        }
    }

    return ret;
}


/** @brief Determine whether a path names the root directory.

    @param pszLocalPath The path to examine; this is a local path, without any
                        volume prefix.

    @return Returns whether @p pszLocalPath names the root directory.

    @retval true    @p pszLocalPath names the root directory.
    @retval false   @p pszLocalPath does not name the root directory.
*/
static bool IsRootDir(
    const char *pszLocalPath)
{
    bool        fRet;

    if(pszLocalPath == NULL)
    {
        REDERROR();
        fRet = false;
    }
    else
    {
        uint32_t    ulIdx = 0U;

        /*  A string containing nothing but path separators (usually only one)
            names the root directory.  An empty string does *not* name the root
            directory, since in POSIX empty strings typically elicit -RED_ENOENT
            errors.
        */
        while(pszLocalPath[ulIdx] == REDCONF_PATH_SEPARATOR)
        {
            ulIdx++;
        }

        fRet = (ulIdx > 0U) && (pszLocalPath[ulIdx] == '\0');
    }

    return fRet;
}


/** @brief Determine whether there are more names in a path.

    Example | Result
    ------- | ------
    ""        false
    "/"       false
    "//"      false
    "a"       true
    "/a"      true
    "//a"     true

    @param pszPathIdx   The path to examine, incremented to the point of
                        interest.

    @return Returns whether there are more names in @p pszPathIdx.

    @retval true    @p pszPathIdx has more names.
    @retval false   @p pszPathIdx has no more names.
*/
static bool PathHasMoreNames(
    const char *pszPathIdx)
{
    bool        fRet;

    if(pszPathIdx == NULL)
    {
        REDERROR();
        fRet = false;
    }
    else
    {
        uint32_t ulIdx = 0U;

        while(pszPathIdx[ulIdx] == REDCONF_PATH_SEPARATOR)
        {
            ulIdx++;
        }

        fRet = pszPathIdx[ulIdx] != '\0';
    }

    return fRet;
}

#endif /* REDCONF_API_POSIX */

