/** @file
    Device Abstraction: Path manipulation utilities.

    Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
    This program and the accompanying materials are licensed and made available under
    the terms and conditions of the BSD License that accompanies this distribution.
    The full text of the license may be found at
    http://opensource.org/licenses/bsd-license.php.

    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include  <Library/BaseLib.h>

#include  <LibConfig.h>

#include  <errno.h>
#include  <stdlib.h>
#include  <wchar.h>
#include  <wctype.h>
#include  <kfile.h>
#include  <Device/Device.h>
#include  <MainData.h>

/** Identify the type of path pointed to by Path.

    Paths are classified based upon their initial character sequences.
      ^\\       Absolute Path
      ^\.       Relative Path
      ^[^:\\]:  Mapping Path
      .*        Relative Path

    Mapping paths are broken into two parts at the ':'.  The part to the left of the ':'
    is the Map Name, pointed to by Path, and the part to the right of the ':' is pointed
    to by NewPath.

    If Path was not a Mapping Path, then NewPath is set to Path.

    @param[in]    Path      Pointer to the path to be classified.
    @param[out]   NewPath   Pointer to the path portion of a mapping path.
    @param[out]   Length    Length of the Map Name portion of the path.

    @retval PathAbsolute  Path is an absolute path. NewPath points to the first '\'.
    @retval PathRelative  Path is a relative path. NewPath = Path.
    @retval PathMapping   Path is a mapping path.  NewPath points to the character following ':'.
    @retval PathError     Path is NULL.
**/
PATH_CLASS
EFIAPI
ClassifyPath(
  IN  wchar_t    *        Path,
  OUT wchar_t   **        NewPath,
  OUT int        * const  Length
  )
{
  size_t    MapLen;

  if(Path == NULL) {
    return PathError;   // Bad parameter
  }
  if(NewPath != NULL) {
    *NewPath = Path;    // Setup default condition
  }
  if((*Path == L'\\') || (*Path == L'\0')) {
    return PathAbsolute;
  }
  if(*Path == L'.') {
    return PathRelative;
  }
  /* The easy stuff has been done, now see if this is a mapping path.
      See if there is a ':' in Path that isn't the first character and is before
      any '\\' characters.
  */
  MapLen = wcscspn(Path, L"\\:");
  if(Length != NULL) {
    *Length = (int)MapLen;
  }
  /*  MapLen == 0       means that the first character is a ':'
             == PathLen means that there are no '\\' or ':'
      Otherwise, Path[MapLen] == ':'  for a mapping path
                              or '\\' for a relative path.
  */
  if(MapLen == 0) {
    return PathError;
  }
  if(Path[MapLen] == L':') {
    if(NewPath != NULL) {
      *NewPath = &Path[MapLen + 1];   // Point to character after then ':'.  Might be '\0'.
    }
    return PathMapping;
  }
  return PathRelative;
}

/*  Normalize a narrow-character path and produce a wide-character path
    that has forward slashes replaced with backslashes.
    Backslashes are directory separators in UEFI File Paths.

    It is the caller's responsibility to eventually free() the returned buffer.

    @param[in]    path    A pointer to the narrow-character path to be normalized.

    @return     A pointer to a buffer containing the normalized, wide-character, path.
*/
wchar_t *
NormalizePath( const char *path)
{
  wchar_t  *temp;
  wchar_t  *OldPath;
  wchar_t  *NewPath;
  size_t    Length;

  OldPath = AsciiStrToUnicodeStr(path, gMD->UString);
  Length  = wcslen(OldPath) + 1;

  NewPath = calloc(Length, sizeof(wchar_t));
  if(NewPath != NULL) {
    temp = NewPath;
    for( ; *OldPath; ++OldPath) {
      if(*OldPath == L'/') {
        *temp = L'\\';
      }
      else {
        *temp = *OldPath;
      }
      ++temp;
    }
  }
  else {
    errno     = ENOMEM;
    EFIerrno  = RETURN_OUT_OF_RESOURCES;
  }
  return NewPath;
}

/** Process a wide character string representing a Mapping Path and extract the instance number.

    The instance number is the sequence of decimal digits immediately to the left
    of the ":" in the Map Name portion of a Mapping Path.

    This function is called with a pointer to beginning of the Map Name.
    Thus Path[Length] must be a ':' and Path[Length - 1] must be a decimal digit.
    If either of these are not true, an instance value of 0 is returned.

    If Path is NULL, an instance value of 0 is returned.

    @param[in]  Path    Points to the beginning of a Mapping Path
    @param[in]  Length  Number of valid characters to the left of the ':'

    @return   Returns either 0 or the value of the contiguous digits to the left of the ':'.
**/
int
EFIAPI
PathInstance(
  const wchar_t  *Path,
        int       Length
  )
{
  wchar_t    *temp;
  int         instance    = 0;

  if((Path != NULL) && (Path[Length] == L':') && (Length > 0)) {
    for(temp = __UNCONST(&Path[Length - 1]); Length > 0; --Length) {
      if(!iswdigit(*temp)) {
        break;
      }
      --temp;
    }
    instance = (int)wcstol(temp+1, NULL, 10);
  }
  return instance;
}

/** Transform a relative path into an absolute path.

    If Path is NULL, return NULL.
    Otherwise, pre-pend the CWD to Path then process the resulting path to:
      - Replace "/./" with "/"
      - Replace "/<dirname>/../" with "/"
      - Do not allow one to back up past the root, "/"

    Also sets the Current Working Device to the Root Device.

    Path must be a previously allocated buffer.  PathAdjust will
    allocate a new buffer to hold the results of the transformation
    and free Path.  A pointer to the newly allocated buffer is returned.

    @param[in]  Path    A pointer to the path to be transformed.  This buffer
                        will always be freed.

    @return   A pointer to a buffer containing the transformed path.
**/
wchar_t *
EFIAPI
PathAdjust(
  wchar_t *Path
  )
{
  wchar_t    *NewPath;

  NewPath = calloc(PATH_MAX, sizeof(wchar_t));
  if(NewPath != NULL) {
    wmemcpy(NewPath, Path, PATH_MAX);
  }
  else {
    errno = ENOMEM;
  }
  free(Path);
  return NewPath;
}

/** Replace the leading portion of Path with any aliases.

    Aliases are read from /etc/fstab.  If there is an associated device, the
    Current Working Device is set to that device.

    Path must be a previously allocated buffer.  PathAlias will
    allocate a new buffer to hold the results of the transformation
    then free Path.  A pointer to the newly allocated buffer is returned.

    @param[in]    Path    A pointer to the original, unaliased, path.  This
                          buffer is always freed.
    @param[out]   Node    Filled in with a pointer to the Device Node describing
                          the device abstraction associated with this path.

    @return     A pointer to a buffer containing the aliased path.
**/
wchar_t *
EFIAPI
PathAlias(
  wchar_t      *Path,
  DeviceNode  **Node
  )
{
  wchar_t    *NewPath;

  NewPath = calloc(PATH_MAX, sizeof(wchar_t));
  if(NewPath != NULL) {
    wmemcpy(NewPath, Path, PATH_MAX);
  }
  else {
    errno = ENOMEM;
  }
  free(Path);
  *Node = NULL;
  return NewPath;
}

/** Parse a path producing the target device, device instance, and file path.

    It is the caller's responsibility to free() FullPath and MapPath when they
    are no longer needed.

    @param[in]    path
    @param[out]   FullPath
    @param[out]   DevNode
    @param[out]   Which
    @param[out]   MapPath       OPTIONAL.  If not NULL, it points to the place to save a pointer
                                to the extracted map name.  If the path didn't have a map name,
                                then *MapPath is set to NULL.

    @retval   RETURN_SUCCESS              The path was parsed successfully.
    @retval   RETURN_NOT_FOUND            The path does not map to a valid device.
    @retval   RETURN_OUT_OF_RESOURCES     Insufficient memory to calloc a MapName buffer.
                                          The errno variable is set to ENOMEM.
    @retval   RETURN_INVALID_PARAMETER    The path parameter is not valid.
                                          The errno variable is set to EINVAL.
**/
RETURN_STATUS
EFIAPI
ParsePath(
  IN    const char   *path,
  OUT   wchar_t     **FullPath,
  OUT   DeviceNode  **DevNode,
  OUT   int          *Which,
  OUT   wchar_t     **MapPath
  )
{
  int                 MapLen;
  PATH_CLASS          PathClass;
  wchar_t            *NewPath;
  wchar_t            *WPath     = NULL;
  wchar_t            *MPath     = NULL;
  DeviceNode         *Node      = NULL;
  RETURN_STATUS       Status    = RETURN_NOT_FOUND;
  int                 Instance  = 0;
  BOOLEAN             ReMapped;

  ReMapped  = FALSE;

  // Convert name from MBCS to WCS and change '/' to '\\'
  WPath = NormalizePath( path);
  PathClass = ClassifyPath(WPath, &NewPath, &MapLen);

reclassify:
  switch(PathClass) {
    case PathMapping:
      if(!ReMapped) {
        if((NewPath == NULL) || (*NewPath == L'\0')) { /* Nothing after the ':' */
          PathClass = PathAbsolute;
        }
        else {
          Instance = PathInstance(WPath, MapLen);
          PathClass = ClassifyPath(NewPath, NULL, NULL);
        }
        ReMapped = TRUE;
        if(WPath[MapLen] == L':') {
          // Get the Map Name, including the trailing ':'. */
          MPath = calloc(MapLen+2, sizeof(wchar_t));
          if(MPath != NULL) {
            wmemcpy(MPath, WPath, MapLen+1);
          }
          else {
            errno = ENOMEM;
            Status = RETURN_OUT_OF_RESOURCES;
            break;    // Exit the switch(PathClass) statement.
          }
        }
        if(WPath != NewPath) {
          /* Shift the RHS of the path down to the start of the buffer. */
          wmemmove(WPath, NewPath, wcslen(NewPath)+1);
          NewPath = WPath;
        }
        goto reclassify;
      }
      /*  Fall through to PathError if Remapped.
          This means that the path looked like "foo:bar:something".
      */

    case PathError:
      errno = EINVAL;
      Status = RETURN_INVALID_PARAMETER;
      break;

    case PathRelative:
      /*  Transform a relative path into an Absolute path.
          Prepends CWD and handles ./ and ../ entries.
          It is the caller's responsibility to free the space
          allocated to WPath.
      */
      WPath = PathAdjust(NewPath);    // WPath was malloc()ed by PathAdjust

    case PathAbsolute:
      /*  Perform any path aliasing.  For example: /dev/foo -> { node.foo, "" }
          The current volume and directory are updated in the path as needed.
          It is the caller's responsibility to free the space
          allocated to WPath.
      */
    Status = RETURN_SUCCESS;
      WPath = PathAlias(WPath, &Node);       // PathAlias frees its argument and malloc()s a new one.
      break;
  }
  if(!RETURN_ERROR(Status)) {
    *FullPath = WPath;
    *Which    = Instance;
    if(MapPath != NULL) {
      *MapPath  = MPath;
    }
    else if(MPath != NULL) {
      free(MPath);    /* Caller doesn't want it so let MPath go free */
    }

    /*  At this point, WPath is an absolute path,
        MPath is either NULL or points to the Map Name,
        and Instance is the instance number.
    */
    if(MPath == NULL) {
      /* This is NOT a mapped path. */
      if(Node == NULL) {
        Node = daDefaultDevice;
      }
      if(Node != NULL) {
        Status = RETURN_SUCCESS;
      }
      else {
        Status = RETURN_NOT_FOUND;
      }
    }
    else {
      /* This is a mapped path. */
      Status = __DevSearch( MPath, NULL, &Node);
      if(Status == RETURN_NOT_FOUND) {
        Node = daDefaultDevice;

        if(Node != NULL) {
          Status = RETURN_SUCCESS;
        }
      }
    }
    if(DevNode != NULL) {
      *DevNode = Node;
    }
  }
  return Status;
}

/**
  Parses a normalized wide character path and returns a pointer to the entry
  following the last \.  If a \ is not found in the path the return value will
  be the same as the input value.  All error conditions return NULL.

  The behavior when passing in a path that has not been normalized is undefined.

  @param  Path - A pointer to a wide character string containing a path to a
                 directory or a file.

  @return Pointer to the file name or terminal directory.  NULL if an error is
          detected.
**/
wchar_t *
EFIAPI
GetFileNameFromPath (
  const wchar_t   *Path
  )
{
  wchar_t   *Tail;

  if (Path == NULL) {
    return NULL;
  }

  Tail = wcsrchr(Path, L'\\');
  if(Tail == NULL) {
    Tail = (wchar_t *) Path;
  } else {
    // Move to the next character after the '\\' to get the file name.
    Tail++;
  }

  return Tail;
}
