/*
 * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0
 * (the “License”). You may not use this work except in compliance with the License, which is
 * available at www.apache.org/licenses/LICENSE-2.0
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied, as more fully set forth in the License.
 *
 * See the NOTICE file distributed with this work for information regarding copyright ownership.
 */

package alluxio.shell.command;

import alluxio.AlluxioURI;
import alluxio.Configuration;
import alluxio.client.file.FileSystem;
import alluxio.client.file.FileSystemUtils;
import alluxio.client.file.URIStatus;
import alluxio.exception.AlluxioException;

import com.google.common.base.Joiner;
import org.apache.commons.cli.CommandLine;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.concurrent.ThreadSafe;

/**
 * Persists a file or directory currently stored only in Alluxio to the UnderFileSystem.
 */
@ThreadSafe
public final class PersistCommand extends AbstractShellCommand {

  /**
   * @param conf the configuration for Alluxio
   * @param fs the filesystem of Alluxio
   */
  public PersistCommand(Configuration conf, FileSystem fs) {
    super(conf, fs);
  }

  @Override
  public String getCommandName() {
    return "persist";
  }

  @Override
  protected int getNumOfArgs() {
    return 1;
  }

  @Override
  public void run(CommandLine cl) throws IOException {
    String[] args = cl.getArgs();
    AlluxioURI inputPath = new AlluxioURI(args[0]);
    persist(inputPath);
  }

  /**
   * Persists a file or directory currently stored only in Alluxio to the UnderFileSystem.
   *
   * @param filePath the {@link AlluxioURI} path to persist to the UnderFileSystem
   * @throws IOException when an Alluxio or I/O error occurs
   */
  private void persist(AlluxioURI filePath) throws IOException {
    try {
      URIStatus status = mFileSystem.getStatus(filePath);
      if (status.isFolder()) {
        List<URIStatus> statuses = mFileSystem.listStatus(filePath);
        List<String> errorMessages = new ArrayList<String>();
        for (URIStatus uriStatus : statuses) {
          AlluxioURI newPath = new AlluxioURI(uriStatus.getPath());
          try {
            persist(newPath);
          } catch (IOException e) {
            errorMessages.add(e.getMessage());
          }
        }
        if (errorMessages.size() != 0) {
          throw new IOException(Joiner.on('\n').join(errorMessages));
        }
      } else if (status.isPersisted()) {
        System.out.println(filePath + " is already persisted");
      } else {
        long size = FileSystemUtils.persistFile(mFileSystem, filePath, status, mConfiguration);
        System.out.println("persisted file " + filePath + " with size " + size);
      }
    } catch (AlluxioException e) {
      throw new IOException(e.getMessage());
    }
  }

  @Override
  public String getUsage() {
    return "persist <alluxioPath>";
  }

  @Override
  public String getDescription() {
    return "Persists a file or directory currently stored only in Alluxio to the UnderFileSystem.";
  }
}

@@ -979,38 +979,45 @@
 /**%0A * Persists 
-a
+several
  file
+s
  or directory cu
@@ -1004,33 +1004,35 @@
 iles or director
-y
+ies
  currently store
@@ -1476,24 +1476,280 @@
 urn 1;%0A  %7D%0A%0A
+  @Override%0A  public boolean validateArgs(String... args) %7B%0A    boolean valid = args.length %3E= getNumOfArgs();%0A    if (!valid) %7B%0A      System.out.println(getCommandName() + %22 takes %22 + getNumOfArgs() + %22 argument at least%5Cn%22);%0A    %7D%0A    return valid;%0A  %7D%0A%0A
   @Override%0A
@@ -1833,24 +1833,57 @@
 .getArgs();%0A
+    for (String path : args) %7B%0A  
     AlluxioU
@@ -1916,18 +1916,17 @@
 URI(
-args%5B0%5D
+path
 );%0A
+  
     
@@ -1945,16 +1945,22 @@
 tPath);%0A
+    %7D%0A
   %7D%0A%0A  /
@@ -3359,17 +3359,52 @@
 uxioPath
-%3E
+1%3E %5BalluxioPath2%5D ... %5BalluxioPathn%5D
 %22;%0A  %7D%0A%0A
@@ -3463,38 +3463,45 @@
 eturn %22Persists 
-a
+several
  file
+s
  or directory cu
@@ -3488,33 +3488,35 @@
 iles or director
-y
+ies
  currently store
@@ -3532,32 +3532,45 @@
  Alluxio to the 
+%22%0A        + %22
 UnderFileSystem.

support persist command to take more than one args