/**
 * 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.hdfs.tools;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.security.PrivilegedExceptionAction;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.hdfs.DistributedFileSystem;
import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier;
import org.apache.hadoop.hdfs.server.namenode.CancelDelegationTokenServlet;
import org.apache.hadoop.hdfs.server.namenode.GetDelegationTokenServlet;
import org.apache.hadoop.hdfs.server.namenode.RenewDelegationTokenServlet;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.security.Credentials;
import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.util.StringUtils;

/**
 * Fetch a DelegationToken from the current Namenode and store it in the
 * specified file.
 */
public class DelegationTokenFetcher {
  private static final String USAGE =
    "fetchdt retrieves delegation tokens (optionally over http)\n" +
    "and writes them to specified file.\n" +
    "Usage: fetchdt [--webservice <namenode http addr>] <output filename>";
  
  private final DistributedFileSystem dfs;
  private final UserGroupInformation ugi;
  private final DataOutputStream out;
  private final Configuration conf;
  private static final Log LOG = 
    LogFactory.getLog(DelegationTokenFetcher.class);
  
  static {
    // Enable Kerberos sockets
    System.setProperty("https.cipherSuites", "TLS_KRB5_WITH_3DES_EDE_CBC_SHA");
  }

  /**
   * Command-line interface
   */
  public static void main(final String [] args) throws Exception {
    // Login the current user
    UserGroupInformation.getCurrentUser().doAs(new PrivilegedExceptionAction<Object>() {
      @Override
      public Object run() throws Exception {
        
        if(args.length == 3 && "--webservice".equals(args[0])) {
          getDTfromRemoteIntoFile(args[1], args[2]);
          return null;
        }
        // avoid annoying mistake
        if(args.length == 1 && "--webservice".equals(args[0])) {
          System.out.println(USAGE);
          return null;
        }
        if(args.length != 1 || args[0].isEmpty()) {
          System.out.println(USAGE);
          return null;
        }
        
        DataOutputStream out = null;
        
        try {
          Configuration conf = new Configuration();
          DistributedFileSystem dfs = (DistributedFileSystem) FileSystem.get(conf);
          out = new DataOutputStream(new FileOutputStream(args[0]));
          UserGroupInformation ugi = UserGroupInformation.getCurrentUser();

          new DelegationTokenFetcher(dfs, out, ugi, conf).go();
          
          out.flush();
          System.out.println("Succesfully wrote token of size " + 
              out.size() + " bytes to "+ args[0]);
        } catch (IOException ioe) {
          System.out.println("Exception encountered:\n" +
              StringUtils.stringifyException(ioe));
        } finally {
          if(out != null) out.close();
        }
        return null;
      }
    });

  }
  
  public DelegationTokenFetcher(DistributedFileSystem dfs, 
      DataOutputStream out, UserGroupInformation ugi, Configuration conf) {
    checkNotNull("dfs", dfs); this.dfs = dfs;
    checkNotNull("out", out); this.out = out;
    checkNotNull("ugi", ugi); this.ugi = ugi;
    checkNotNull("conf",conf); this.conf = conf;
  }
  
  private void checkNotNull(String s, Object o) {
    if(o == null) throw new IllegalArgumentException(s + " cannot be null.");
  }

  public void go() throws IOException {
    String fullName = ugi.getUserName();
    String shortName = ugi.getShortUserName();
    Token<DelegationTokenIdentifier> token = 
      dfs.getDelegationToken(new Text(fullName));
    
    // Reconstruct the ip:port of the Namenode
    URI uri = FileSystem.getDefaultUri(conf);
    String nnAddress = 
      InetAddress.getByName(uri.getHost()).getHostAddress() + ":" + uri.getPort();
    token.setService(new Text(nnAddress));
    
    Credentials ts = new Credentials();
    ts.addToken(new Text(shortName), token);
    ts.writeTokenStorageToStream(out);
  }

  /**
   * Utility method to obtain a delegation token over http
   * @param nnHttpAddr Namenode http addr, such as http://namenode:50070
   */
  static public Credentials getDTfromRemote(String nnAddr, 
                                            String renewer) throws IOException {
    DataInputStream dis = null;

    try {
      StringBuffer url = new StringBuffer();
      if (renewer != null) {
        url.append(nnAddr).append(GetDelegationTokenServlet.PATH_SPEC).append("?").
        append(GetDelegationTokenServlet.RENEWER).append("=").append(renewer);
      } else {
        url.append(nnAddr).append(GetDelegationTokenServlet.PATH_SPEC);
      }
      System.out.println("Retrieving token from: " + url);
      URL remoteURL = new URL(url.toString());
      SecurityUtil.fetchServiceTicket(remoteURL);
      URLConnection connection = remoteURL.openConnection();

      InputStream in = connection.getInputStream();
      Credentials ts = new Credentials();
      dis = new DataInputStream(in);
      ts.readFields(dis);
      return ts;
    } catch (Exception e) {
      throw new IOException("Unable to obtain remote token", e);
    } finally {
      if(dis != null) dis.close();
    }
  }
  
  /**
   * Renew a Delegation Token.
   * @param nnAddr the NameNode's address
   * @param tok the token to renew
   * @return the Date that the token will expire next.
   * @throws IOException
   */
  static public long renewDelegationToken(String nnAddr,
                                          Token<DelegationTokenIdentifier> tok
                                          ) throws IOException {
    StringBuilder buf = new StringBuilder();
    buf.append(nnAddr);
    buf.append(RenewDelegationTokenServlet.PATH_SPEC);
    buf.append("?");
    buf.append(RenewDelegationTokenServlet.TOKEN);
    buf.append("=");
    buf.append(tok.encodeToUrlString());
    BufferedReader in = null;
    HttpURLConnection connection = null;
    try {
      URL url = new URL(buf.toString());
      SecurityUtil.fetchServiceTicket(url);
      connection = (HttpURLConnection)url.openConnection();
      in = new BufferedReader(new InputStreamReader
                              (connection.getInputStream()));
      long result = Long.parseLong(in.readLine());
      in.close();
      return result;
    } catch (IOException ie) {
      LOG.info("error in renew over HTTP", ie);
      IOException e = null;
      if(connection != null) {
        String resp = connection.getResponseMessage();
        e = getExceptionFromResponse(resp);
      }
      
      IOUtils.cleanup(LOG, in);
      if(e!=null) {
        LOG.info("rethrowing exception from HTTP request: " + e.getLocalizedMessage());
        throw e;
      }
      throw ie;
    }
  }

  static private IOException getExceptionFromResponse(String resp) {
    String exceptionClass = "", exceptionMsg = "";
    if(resp != null && !resp.isEmpty()) {
      String[] rs = resp.split(";");
      exceptionClass = rs[0];
      exceptionMsg = rs[1];
    }
    LOG.info("Error response from HTTP request=" + resp + 
        ";ec=" + exceptionClass + ";em="+exceptionMsg);
    IOException e = null;
    if(exceptionClass != null  && !exceptionClass.isEmpty()) {
      if(exceptionClass.contains("InvalidToken")) {
        e = new org.apache.hadoop.security.token.SecretManager.InvalidToken(exceptionMsg);
        e.setStackTrace(new StackTraceElement[0]); // stack is not relevant
      } else if(exceptionClass.contains("AccessControlException")) {
        e = new org.apache.hadoop.security.AccessControlException(exceptionMsg);
        e.setStackTrace(new StackTraceElement[0]); // stack is not relevant
      }
    }
    LOG.info("Exception from HTTP response=" + e.getLocalizedMessage());
    return e;
  }
  
  /**
   * Cancel a Delegation Token.
   * @param nnAddr the NameNode's address
   * @param tok the token to cancel
   * @throws IOException
   */
  static public void cancelDelegationToken(String nnAddr,
                                           Token<DelegationTokenIdentifier> tok
                                           ) throws IOException {
    StringBuilder buf = new StringBuilder();
    buf.append(nnAddr);
    buf.append(CancelDelegationTokenServlet.PATH_SPEC);
    buf.append("?");
    buf.append(CancelDelegationTokenServlet.TOKEN);
    buf.append("=");
    buf.append(tok.encodeToUrlString());
    BufferedReader in = null;
    try {
      URL url = new URL(buf.toString());
      SecurityUtil.fetchServiceTicket(url);
      HttpURLConnection connection = (HttpURLConnection) url.openConnection();
      if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
        throw new IOException("Error cancelling token:" + 
                              connection.getResponseMessage());
      }
    } catch (IOException ie) {
      IOUtils.cleanup(LOG, in);
      throw ie;
    }
  }

  /**
   * Utility method to obtain a delegation token over http
   * @param nnHttpAddr Namenode http addr, such as http://namenode:50070
   * @param filename Name of file to store token in
   */
  static private void getDTfromRemoteIntoFile(String nnAddr, String filename) 
  throws IOException {
    Credentials ts = getDTfromRemote(nnAddr, null); 

    DataOutputStream file = new DataOutputStream(new FileOutputStream(filename));
    ts.writeTokenStorageToStream(file);
    file.flush();
    System.out.println("Successfully wrote token of " + file.size() 
        + " bytes  to " + filename);
  }
}
