/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.hadoop.fs;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.util.Shell;

import com.google.common.annotations.VisibleForTesting;

/**
 * Wrapper for the Unix stat(1) command. Used to workaround the lack of 
 * lstat(2) in Java 6.
 */
@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
@InterfaceStability.Evolving
public class Stat extends Shell {

  private final Path original;
  private final Path qualified;
  private final Path path;
  private final long blockSize;
  private final boolean dereference;

  private FileStatus stat;

  public Stat(Path path, long blockSize, boolean deref, FileSystem fs)
      throws IOException {
    super(0L, true);
    // Original path
    this.original = path;
    // Qualify the original and strip out URI fragment via toUri().getPath()
    Path stripped = new Path(
        original.makeQualified(fs.getUri(), fs.getWorkingDirectory())
        .toUri().getPath());
    // Re-qualify the bare stripped path and store it
    this.qualified = 
        stripped.makeQualified(fs.getUri(), fs.getWorkingDirectory());
    // Strip back down to a plain path
    this.path = new Path(qualified.toUri().getPath());
    this.blockSize = blockSize;
    this.dereference = deref;
    // LANG = C setting
    Map<String, String> env = new HashMap<String, String>();
    env.put("LANG", "C");
    setEnvironment(env);
  }

  public FileStatus getFileStatus() throws IOException {
    run();
    return stat;
  }

  /**
   * Whether Stat is supported on the current platform
   * @return
   */
  public static boolean isAvailable() {
    if (Shell.LINUX || Shell.FREEBSD || Shell.MAC) {
      return true;
    }
    return false;
  }

  @VisibleForTesting
  FileStatus getFileStatusForTesting() {
    return stat;
  }

  @Override
  protected String[] getExecString() {
    String derefFlag = "-";
    if (dereference) {
      derefFlag = "-L";
    }
    if (Shell.LINUX) {
      return new String[] {
          "stat", derefFlag + "c", "%s,%F,%Y,%X,%a,%U,%G,%N", path.toString() };
    } else if (Shell.FREEBSD || Shell.MAC) {
      return new String[] {
          "stat", derefFlag + "f", "%z,%HT,%m,%a,%Op,%Su,%Sg,`link' -> `%Y'",
          path.toString() };
    } else {
      throw new UnsupportedOperationException(
          "stat is not supported on this platform");
    }
  }

  @Override
  protected void parseExecResult(BufferedReader lines) throws IOException {
    // Reset stat
    stat = null;

    String line = lines.readLine();
    if (line == null) {
      throw new IOException("Unable to stat path: " + original);
    }
    if (line.endsWith("No such file or directory") ||
        line.endsWith("Not a directory")) {
      throw new FileNotFoundException("File " + original + " does not exist");
    }
    if (line.endsWith("Too many levels of symbolic links")) {
      throw new IOException("Possible cyclic loop while following symbolic" +
          " link " + original);
    }
    // 6,symbolic link,6,1373584236,1373584236,lrwxrwxrwx,andrew,andrew,`link' -> `target'
    // OR
    // 6,symbolic link,6,1373584236,1373584236,lrwxrwxrwx,andrew,andrew,'link' -> 'target'
    StringTokenizer tokens = new StringTokenizer(line, ",");
    try {
      long length = Long.parseLong(tokens.nextToken());
      boolean isDir = tokens.nextToken().equalsIgnoreCase("directory") ? true
          : false;
      // Convert from seconds to milliseconds
      long modTime = Long.parseLong(tokens.nextToken())*1000;
      long accessTime = Long.parseLong(tokens.nextToken())*1000;
      String octalPerms = tokens.nextToken();
      // FreeBSD has extra digits beyond 4, truncate them
      if (octalPerms.length() > 4) {
        int len = octalPerms.length();
        octalPerms = octalPerms.substring(len-4, len);
      }
      FsPermission perms = new FsPermission(Short.parseShort(octalPerms, 8));
      String owner = tokens.nextToken();
      String group = tokens.nextToken();
      String symStr = tokens.nextToken();
      // 'notalink'
      // `link' -> `target' OR 'link' -> 'target'
      // '' -> ''
      Path symlink = null;
      String parts[] = symStr.split(" -> ");      
      try {
        String target = parts[1];
        target = target.substring(1, target.length()-1);
        if (!target.isEmpty()) {
          symlink = new Path(target);
        }
      } catch (ArrayIndexOutOfBoundsException e) {
        // null if not a symlink
      }
      // Set stat
      stat = new FileStatus(length, isDir, 1, blockSize, modTime, accessTime,
          perms, owner, group, symlink, qualified);
    } catch (NumberFormatException e) {
      throw new IOException("Unexpected stat output: " + line, e);
    } catch (NoSuchElementException e) {
      throw new IOException("Unexpected stat output: " + line, e);
    }
  }
}
