/*
 * 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.chukwa.hicc;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.apache.hadoop.chukwa.conf.ChukwaConfiguration;
import org.apache.hadoop.chukwa.util.ExceptionUtil;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.mortbay.jetty.Server;
import org.mortbay.xml.XmlConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class HiccWebServer {
  private static Log log = LogFactory.getLog(HiccWebServer.class);
  private static URL serverConf = HiccWebServer.class.getResource("/WEB-INF/jetty.xml");
  private Server server = null;
  private String chukwaHdfs;
  private String hiccData;
  private static HiccWebServer instance = null;
  private static final Configuration config = new Configuration();
  protected static final ChukwaConfiguration chukwaConf = new ChukwaConfiguration();

  protected HiccWebServer() {
  }
 
  public static HiccWebServer getInstance() {
    if(instance==null) {
      instance = new HiccWebServer();
    }
    if(serverConf==null) {
      log.error("Unable to locate jetty-web.xml.");
      throw new RuntimeException("Unable to locate jetty-web.xml.");
    }
    return instance;
  }

  public void start() {
    try {
      chukwaHdfs = config.get("fs.defaultFS")+File.separator+chukwaConf.get("chukwa.data.dir");
      hiccData = chukwaHdfs+File.separator+"hicc";
      setupDefaultData();
      run();
    } catch(Exception e) {
      log.error("HDFS unavailable, check configuration in chukwa-env.sh.");
      throw new RuntimeException("Bail out!");
    }
  }

  public static Configuration getConfig() {
    return config;
  }
  
  public List<String> getResourceListing(String path) throws URISyntaxException, IOException {
    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
    URL dirURL = contextClassLoader.getResource(path);

    if (dirURL == null) {
      dirURL = contextClassLoader.getResource(path);
    }
    
    if (dirURL.getProtocol().equals("jar")) {
      /* A JAR path */
      String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf("!")); //strip out only the JAR file
      JarFile jar = new JarFile(jarPath);
      Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
      List<String> result = new ArrayList<String>(); //avoid duplicates in case it is a subdirectory
      while(entries.hasMoreElements()) {
        String name = entries.nextElement().getName();
        if (name.startsWith(path)) { //filter according to the path
          String entry = name.substring(path.length());
          int checkSubdir = entry.indexOf("/");
          if (checkSubdir == 0 && entry.length()>1) {
            // if it is a subdirectory, we just return the directory name
            result.add(name);
          }
        }
      }
      jar.close();
      return result;
    } 
      
    throw new UnsupportedOperationException("Cannot list files for URL "+dirURL);
  }
  
  public void populateDir(List<String> files, Path path) {
    try {
      FileSystem fs = FileSystem.get(config);
      ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
      for(String source : files) {
        String name = source.substring(source.indexOf(File.separator));
        Path dest = new Path(path.toString()+File.separator+name);
        InputStream is = contextClassLoader.getResourceAsStream(source);
        StringBuilder sb = new StringBuilder();
        String line = null;
        try {
          BufferedReader reader = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
          while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
          }
          FSDataOutputStream out = fs.create(dest);
          out.write(sb.toString().getBytes(Charset.forName("UTF-8")));
          out.close();
          reader.close();
        } catch(IOException e) {
            log.error("Error writing file: "+dest.toString());
        }
      }
    } catch(IOException e) {
      log.error("HDFS unavailable, check configuration in chukwa-env.sh.");
    }
  }
  
  public void setupDefaultData() {
    Path hiccPath = new Path(hiccData);
    try {
      FileSystem fs = FileSystem.get(config);
      if(!fs.exists(hiccPath)) {
        log.info("Initializing HICC Datastore.");
        // Create chukwa directory
        if(!fs.exists(new Path(chukwaHdfs))) {
          fs.mkdirs(new Path(chukwaHdfs));
        }
        
        // Create hicc directory        
        fs.mkdirs(hiccPath);
        
        // Populate widgets repository
        StringBuffer hiccWidgets = new StringBuffer();
        hiccWidgets.append(hiccData);
        hiccWidgets.append(File.separator);
        hiccWidgets.append("widgets");
        Path widgetsPath = new Path(hiccWidgets.toString());
        fs.mkdirs(widgetsPath);
        List<String> widgets = getResourceListing("descriptors");
        populateDir(widgets, widgetsPath);
        
        // Create views directory
        StringBuffer hiccViews = new StringBuffer();
        hiccViews.append(hiccData);
        hiccViews.append(File.separator);
        hiccViews.append("views");        
        fs.mkdirs(new Path(hiccViews.toString()));
        
        // Create users repository
        StringBuffer hiccUsers = new StringBuffer();
        hiccUsers.append(hiccViews);
        hiccUsers.append(File.separator);
        hiccUsers.append("users");
        fs.mkdirs(new Path(hiccUsers.toString()));

        // Populate public repository
        StringBuffer hiccPublic = new StringBuffer();
        hiccPublic.append(hiccViews);
        hiccPublic.append(File.separator);
        hiccPublic.append("public");
        Path viewsPath = new Path(hiccPublic.toString());
        fs.mkdirs(viewsPath);
        List<String> views = getResourceListing("views");
        populateDir(views, viewsPath);

        log.info("HICC Datastore initialization completed.");
      }
    } catch (IOException ex) {
      log.error(ExceptionUtil.getStackTrace(ex));
    } catch (URISyntaxException ex) {
      log.error(ExceptionUtil.getStackTrace(ex));      
    }
  }

  public void run() {
    server = new Server();
    XmlConfiguration configuration;
    try {
      configuration = new XmlConfiguration(serverConf);
      configuration.configure(server);
      server.start();
    } catch (Exception e) {
      log.error(ExceptionUtil.getStackTrace(e));
    }     
  }
  
  public void shutdown() {
    try {
      server.stop();
    } catch (Exception e) {
      log.error(ExceptionUtil.getStackTrace(e));
    }
  }
  
  public static void main(String[] args) {
    HiccWebServer hicc = HiccWebServer.getInstance();
    hicc.start();
    System.out.close();
    System.err.close();
  }

}
