/** @file
  Main file for attrib shell level 2 function.

  Copyright (c) 2009 - 2013, 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
  which 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 "UefiShellLevel2CommandsLib.h"

STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
  {L"-q", TypeFlag},
  {NULL, TypeMax}
  };

/**
  Determine if a directory has no files in it.

  @param[in] FileHandle   The EFI_HANDLE to the directory.
  
  @retval TRUE  The directory has no files (or directories).
  @retval FALSE The directory has at least 1 file or directory in it.
**/
BOOLEAN
EFIAPI
IsDirectoryEmpty (
  IN EFI_HANDLE   FileHandle
  )
{
  EFI_FILE_INFO   *FileInfo;
  BOOLEAN         NoFile;
  BOOLEAN         RetVal;

  RetVal = TRUE;
  NoFile = FALSE;

  for (FileHandleFindFirstFile(FileHandle, &FileInfo)
    ;  !NoFile
    ;  FileHandleFindNextFile(FileHandle, FileInfo, &NoFile)
   ){
    if (StrStr(FileInfo->FileName, L".") != FileInfo->FileName
      &&StrStr(FileInfo->FileName, L"..") != FileInfo->FileName) {
      RetVal = FALSE;
    }
  }
  return (RetVal);
}

/**
  Delete a node and all nodes under it (including sub directories).

  @param[in] Node   The node to start deleting with.
  @param[in] Quiet  TRUE to print no messages.

  @retval SHELL_SUCCESS       The operation was successful.
  @retval SHELL_ACCESS_DENIED A file was read only.
  @retval SHELL_ABORTED       The abort message was received.
  @retval SHELL_DEVICE_ERROR  A device error occured reading this Node.
**/
SHELL_STATUS
EFIAPI
CascadeDelete(
  IN EFI_SHELL_FILE_INFO  *Node,
  IN CONST BOOLEAN        Quiet
  )
{
  SHELL_STATUS          ShellStatus;
  EFI_SHELL_FILE_INFO   *List;
  EFI_SHELL_FILE_INFO   *Node2;
  EFI_STATUS            Status;
  SHELL_PROMPT_RESPONSE *Resp;
  CHAR16                *TempName;

  Resp                  = NULL;
  ShellStatus           = SHELL_SUCCESS;
  List                  = NULL;
  Status                = EFI_SUCCESS;

  if ((Node->Info->Attribute & EFI_FILE_READ_ONLY) == EFI_FILE_READ_ONLY) {
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DETELE_RO), gShellLevel2HiiHandle, Node->FullName);
    return (SHELL_ACCESS_DENIED);
  }

  if ((Node->Info->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {
    if (!IsDirectoryEmpty(Node->Handle)) {
      if (!Quiet) {
        Status = ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_RM_LOG_DELETE_CONF), gShellLevel2HiiHandle, Node->FullName);
        Status = ShellPromptForResponse(ShellPromptResponseTypeYesNo, NULL, (VOID**)&Resp);
        ASSERT(Resp != NULL);
        if (EFI_ERROR(Status) || *Resp != ShellPromptResponseYes) {
          SHELL_FREE_NON_NULL(Resp);
          return (SHELL_ABORTED);
        }
        SHELL_FREE_NON_NULL(Resp);
      }
      //
      // empty out the directory
      //
      Status = gEfiShellProtocol->FindFilesInDir(Node->Handle, &List);
      if (EFI_ERROR(Status)) {
        if (List!=NULL) {
          gEfiShellProtocol->FreeFileList(&List);
        }
        return (SHELL_DEVICE_ERROR);
      }
      for (Node2 = (EFI_SHELL_FILE_INFO   *)GetFirstNode(&List->Link)
        ;  !IsNull(&List->Link, &Node2->Link)
        ;  Node2 = (EFI_SHELL_FILE_INFO   *)GetNextNode(&List->Link, &Node2->Link)
       ){
        //
        // skip the directory traversing stuff...
        //
        if (StrCmp(Node2->FileName, L".") == 0 || StrCmp(Node2->FileName, L"..") == 0) {
          continue;
        }
        Node2->Status = gEfiShellProtocol->OpenFileByName (Node2->FullName, &Node2->Handle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE);
        if (EFI_ERROR(Node2->Status) && StrStr(Node2->FileName, L":") == NULL) {
          //
          // Update the node filename to have full path with file system identifier
          //
          TempName = AllocateZeroPool(StrSize(Node->FullName) + StrSize(Node2->FullName));
          if (TempName == NULL) {
            ShellStatus = SHELL_OUT_OF_RESOURCES;
          } else {
            StrCpy(TempName, Node->FullName);
            TempName[StrStr(TempName, L":")+1-TempName] = CHAR_NULL;
            StrCat(TempName, Node2->FullName);
            FreePool((VOID*)Node2->FullName);
            Node2->FullName = TempName;

            //
            // Now try again to open the file
            //
            Node2->Status = gEfiShellProtocol->OpenFileByName (Node2->FullName, &Node2->Handle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE);
          }
        }
        if (!EFI_ERROR(Node2->Status)) {
          ShellStatus = CascadeDelete(Node2, Quiet);
        } else if (ShellStatus == SHELL_SUCCESS) {
          ShellStatus = (SHELL_STATUS)(Node2->Status&(~0x80000000));
        }
        if (ShellStatus != SHELL_SUCCESS) {
          if (List!=NULL) {
            gEfiShellProtocol->FreeFileList(&List);
          }
          return (ShellStatus);
        }
      }
      if (List!=NULL) {
        gEfiShellProtocol->FreeFileList(&List);
      }
    }
  }

  if (!(StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0)) {
    //
    // now delete the current node...
    //
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE), gShellLevel2HiiHandle, Node->FullName);
    Status = gEfiShellProtocol->DeleteFile(Node->Handle);
    Node->Handle = NULL;
  }

  //
  // We cant allow for the warning here! (Dont use EFI_ERROR Macro).
  //
  if (Status != EFI_SUCCESS){
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_ERR), gShellLevel2HiiHandle, Status);
    return (SHELL_ACCESS_DENIED);
  } else {
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_COMP), gShellLevel2HiiHandle);
    return (SHELL_SUCCESS);
  }
}

/**
  Determins if a Node is a valid delete target.  Will prevent deleting the root directory.

  @param[in] List       RESERVED.  Not used.
  @param[in] Node       The node to analyze.
  @param[in] Package    RESERVED.  Not used.
**/
BOOLEAN
EFIAPI
IsValidDeleteTarget(
  IN CONST EFI_SHELL_FILE_INFO  *List,
  IN CONST EFI_SHELL_FILE_INFO  *Node,
  IN CONST LIST_ENTRY           *Package
  )
{
  CONST CHAR16        *TempLocation;
  BOOLEAN             RetVal;
  CHAR16              *SearchString;
  CHAR16              *Pattern;
  UINTN               Size;

  if (Node == NULL || Node->FullName == NULL) {
    return (FALSE);
  }

  TempLocation = StrStr(Node->FullName, L":");
  if (StrLen(TempLocation) <= 2) {
    //
    // Deleting the root directory is invalid.
    //
    return (FALSE);
  }

  TempLocation = ShellGetCurrentDir(NULL);
  if (TempLocation == NULL) {
    //
    // No working directory is specified so whatever is left is ok.
    //
    return (TRUE);
  }

  Pattern       = NULL;
  SearchString  = NULL;
  Size          = 0;
  Pattern       = StrnCatGrow(&Pattern     , NULL, TempLocation  , 0);
  SearchString  = StrnCatGrow(&SearchString, &Size, Node->FullName, 0);
  if (!EFI_ERROR(ShellIsDirectory(SearchString))) {
    SearchString  = StrnCatGrow(&SearchString, &Size, L"\\", 0);
    SearchString  = StrnCatGrow(&SearchString, &Size, L"*", 0);
  }

  if (Pattern == NULL || SearchString == NULL) {
    RetVal = FALSE;
  } else {
    RetVal = TRUE;
    if (gUnicodeCollation->MetaiMatch(gUnicodeCollation, Pattern, SearchString)) {
      RetVal = FALSE;
    }
  }

  SHELL_FREE_NON_NULL(Pattern     );
  SHELL_FREE_NON_NULL(SearchString);

  return (RetVal);
}

/**
  Function for 'rm' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunRm (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS            Status;
  LIST_ENTRY            *Package;
  CHAR16                *ProblemParam;
  CONST CHAR16          *Param;
  SHELL_STATUS          ShellStatus;
  UINTN                 ParamCount;
  EFI_SHELL_FILE_INFO   *FileList;
  EFI_SHELL_FILE_INFO   *Node;

  ProblemParam        = NULL;
  ShellStatus         = SHELL_SUCCESS;
  ParamCount          = 0;
  FileList            = NULL;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize();
  ASSERT_EFI_ERROR(Status);

  //
  // parse the command line
  //
  Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR(Status)) {
    if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);
      FreePool(ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT(FALSE);
    }
  } else {
    //
    // check for "-?"
    //
    if (ShellCommandLineGetFlag(Package, L"-?")) {
      ASSERT(FALSE);
    }
    if (ShellCommandLineGetRawValue(Package, 1) == NULL) {
      //
      // we insufficient parameters
      //
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      //
      // get a list with each file specified by parameters
      // if parameter is a directory then add all the files below it to the list
      //
      for ( ParamCount = 1, Param = ShellCommandLineGetRawValue(Package, ParamCount)
          ; Param != NULL
          ; ParamCount++, Param = ShellCommandLineGetRawValue(Package, ParamCount)
         ){
        Status = ShellOpenFileMetaArg((CHAR16*)Param, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);
        if (EFI_ERROR(Status) || FileList == NULL || IsListEmpty(&FileList->Link)) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, (CHAR16*)Param);
          ShellStatus = SHELL_NOT_FOUND;
          break;
        }
      }

      if (ShellStatus == SHELL_SUCCESS){
        //
        // loop through the list and make sure we are not aborting...
        //
        for ( Node = (EFI_SHELL_FILE_INFO*)GetFirstNode(&FileList->Link)
            ; !IsNull(&FileList->Link, &Node->Link) && !ShellGetExecutionBreakFlag()
            ; Node = (EFI_SHELL_FILE_INFO*)GetNextNode(&FileList->Link, &Node->Link)
           ){
          //
          // skip the directory traversing stuff...
          //
          if (StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0) {
            continue;
          }

          //
          // do the deleting of nodes
          //
          if (EFI_ERROR(Node->Status)){
            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_ERR2), gShellLevel2HiiHandle, Node->Status);
            ShellStatus = SHELL_ACCESS_DENIED;
            break;
          }
          if (!IsValidDeleteTarget(FileList, Node, Package)) {
            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_ERR3), gShellLevel2HiiHandle, Node->FullName);
            ShellStatus = SHELL_INVALID_PARAMETER;
            break;
          }

          ShellStatus = CascadeDelete(Node, ShellCommandLineGetFlag(Package, L"-q"));
        }
      }
      //
      // Free the fileList
      //
      if (FileList != NULL) {
        Status = ShellCloseFileMetaArg(&FileList);
      }
      FileList = NULL;
    }

    //
    // free the command line package
    //
    ShellCommandLineFreeVarList (Package);
  }

  return (ShellStatus);
}

