/** @file
  Main file for attrib shell level 2 function.

  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2015, 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;
  FileInfo = NULL;

  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;
  UINTN                 NewSize;

  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, L"rm", 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
          //
          NewSize = StrSize(Node->FullName) + StrSize(Node2->FullName);
          TempName = AllocateZeroPool(NewSize);
          if (TempName == NULL) {
            ShellStatus = SHELL_OUT_OF_RESOURCES;
          } else {
            StrCpyS(TempName, NewSize/sizeof(CHAR16), Node->FullName);
            TempName[StrStr(TempName, L":")+1-TempName] = CHAR_NULL;
            StrCatS(TempName, NewSize/sizeof(CHAR16), 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...
    //
    if (!Quiet) {
      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 {
    if (!Quiet) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_COMP), gShellLevel2HiiHandle);
    }
    return (SHELL_SUCCESS);
  }
}

/**
  Determines 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, &Size, TempLocation  , 0);
  Pattern       = StrnCatGrow(&Pattern, &Size, L"\\"  , 0);
  Size = 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, L"rm", 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, L"rm");  
      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, L"rm", (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);
}

