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

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.chukwa.util.DatabaseWriter;

public class Macro {
    private static Log log = LogFactory.getLog(Macro.class);
    private boolean forCharting = false;
    private long current = 0;
    private long start = 0;
    private long end = 0;
    private static DatabaseConfig dbc = new DatabaseConfig();
    private DatabaseWriter db = null;
    private String query = null;
    private HttpServletRequest request = null;

    public Macro(long timestamp, String query) {
        this.current = timestamp;
        this.start = timestamp;
        this.end = timestamp;
        this.query = query;
    }

    public Macro(long startTime, long endTime, String query) {
        this.current = endTime;
        this.start = startTime;
        this.end = endTime;
        forCharting = true;	
        this.query = query;
    }
    
    public Macro(long startTime, long endTime, String query, HttpServletRequest request) {
        this.request = request;
        this.current = endTime;
        this.start = startTime;
        this.end = endTime;
        forCharting = true; 
        this.query = query;        
    }
    public HashMap<String,String> findMacros(String query) throws SQLException {
        boolean add=false;
        HashMap<String,String> macroList = new HashMap<String,String>();
        String macro="";
        for(int i=0;i<query.length();i++) {
            if(query.charAt(i)==']') {
                add=false;
                if(!macroList.containsKey(macro)) {
                    String subString = computeMacro(macro);
                    macroList.put(macro,subString);	    			
                }
                macro="";
            }
            if(add) {
                macro=macro+query.charAt(i);
            }
            if(query.charAt(i)=='[') {
                add=true;
            }
        }
        return macroList;
    }

    public String computeMacro(String macro) throws SQLException {
        Pattern p = Pattern.compile("past_(.*)_minutes");
        Matcher matcher = p.matcher(macro);
        if(macro.indexOf("avg(")==0 || macro.indexOf("group_avg(")==0 || macro.indexOf("sum(")==0) {
            String meta="";
            String[] table = null;
            if(forCharting) {
                table = dbc.findTableNameForCharts(macro.substring(macro.indexOf("(")+1,macro.indexOf(")")), start, end);
            } else {
                table = dbc.findTableName(macro.substring(macro.indexOf("(")+1,macro.indexOf(")")), start, end);
            }
            try {
                String cluster = System.getProperty("CLUSTER");
                if(cluster==null) {
                    cluster="unknown";
                }
                db = new DatabaseWriter(cluster);
                DatabaseMetaData dbMetaData = db.getConnection().getMetaData();
                ResultSet rs = dbMetaData.getColumns ( null,null,table[0], null);
                boolean first=true;
                while(rs.next()) {
                    if(!first) {
                        meta = meta+",";
                    }
                    String name = rs.getString(4);
                    int type = rs.getInt(5);
                    if(type==java.sql.Types.VARCHAR) {
                        if(macro.indexOf("group_avg(")<0) {
                            meta=meta+"count("+name+") as "+name;
                        } else {
                            meta=meta+name;
                        }
                        first=false;
                    } else if(type==java.sql.Types.DOUBLE ||
                            type==java.sql.Types.FLOAT ||
                            type==java.sql.Types.INTEGER) {
                        if(macro.indexOf("sum(")==0) {
                            meta=meta+"sum("+name+")";	            			
                        } else {
                            meta=meta+"avg("+name+")";
                        }
                        first=false;
                    } else if(type==java.sql.Types.TIMESTAMP) {
                        meta=meta+name;	            			
                        first=false;
                    } else {
                        if(macro.indexOf("sum(")==0) {
                            meta=meta+"SUM("+name+")";
                        } else {
                            meta=meta+"AVG("+name+")";	            			
                        }
                        first=false;
                    }
                }
                db.close();
                if(first) {
                    throw new SQLException("Table is undefined.");
                }
            } catch(SQLException ex) {
                throw new SQLException("Table does not exist:"+ table[0]);
            }
            return meta;
        } else if(macro.indexOf("now")==0) {
            return DatabaseWriter.formatTimeStamp(current);
        } else if(macro.intern()=="start".intern()) {
            return DatabaseWriter.formatTimeStamp(start);
        } else if(macro.intern()=="end".intern()) {
            return DatabaseWriter.formatTimeStamp(end);
        } else if(matcher.find()) {
            int period = Integer.parseInt(matcher.group(1));
            long timestamp = current - (current % (period*60*1000L)) - (period*60*1000L);
            return DatabaseWriter.formatTimeStamp(timestamp);
        } else if(macro.indexOf("past_hour")==0) {
            return DatabaseWriter.formatTimeStamp(current-3600*1000L);
        } else if(macro.endsWith("_week")) {
            long partition = current / DatabaseConfig.WEEK;
            if(partition<=0) {
                partition=1;
            }
            String[] buffers = macro.split("_");
            StringBuffer tableName = new StringBuffer();
            for(int i=0;i<buffers.length-1;i++) {
                tableName.append(buffers[i]);
                tableName.append("_");
            }
            tableName.append(partition);
            tableName.append("_week");
            return tableName.toString();
        } else if(macro.endsWith("_month")) {
            long partition = current / DatabaseConfig.MONTH;
            if(partition<=0) {
                partition=1;
            }
            String[] buffers = macro.split("_");
            StringBuffer tableName = new StringBuffer();
            for(int i=0;i<buffers.length-1;i++) {
                tableName.append(buffers[i]);
                tableName.append("_");
            }
            tableName.append(partition);
            tableName.append("_month");
            return tableName.toString();
        } else if(macro.endsWith("_quarter")) {
            long partition = current / DatabaseConfig.QUARTER;
            if(partition<=0) {
                partition=1;
            }
            String[] buffers = macro.split("_");
            StringBuffer tableName = new StringBuffer();
            for(int i=0;i<buffers.length-1;i++) {
                tableName.append(buffers[i]);
                tableName.append("_");
            }
            tableName.append(partition);
            tableName.append("_quarter");
            return tableName.toString();
        } else if(macro.endsWith("_year")) {
            long partition = current / DatabaseConfig.YEAR;
            if(partition<=0) {
                partition=1;
            }
            String[] buffers = macro.split("_");
            StringBuffer tableName = new StringBuffer();
            for(int i=0;i<buffers.length-1;i++) {
                tableName.append(buffers[i]);
                tableName.append("_");
            }
            tableName.append(partition);
            tableName.append("_year");
            return tableName.toString();
        } else if(macro.endsWith("_decade")) {
            long partition = current / DatabaseConfig.DECADE;
            if(partition<=0) {
                partition=1;
            }
            String[] buffers = macro.split("_");
            StringBuffer tableName = new StringBuffer();
            for(int i=0;i<buffers.length-1;i++) {
                tableName.append(buffers[i]);
                tableName.append("_");
            }
            tableName.append(partition);
            tableName.append("_decade");
            return tableName.toString();
        }
        if(forCharting) {
            if(macro.startsWith("session(") && request!=null){
                String keyword = macro.substring(macro.indexOf("(")+1,macro.indexOf(")"));
                String[] objects = null;
                if(request.getSession().getAttribute(keyword)!=null) {
                    objects = ((String)request.getSession().getAttribute(keyword)).split(",");
                }
                StringBuffer buf = new StringBuffer();
                boolean first = true;
                if(objects!=null) {
                    for(String object : objects) {
                        if(!first) {
                            buf.append(" or ");
                        }
                        first = false;
                        buf.append(macro.substring(macro.indexOf("(")+1,macro.indexOf(")"))+"='"+object+"'");
                    }
                    return buf.toString();
                }
                return "";
            } else {
                String[] tableList = dbc.findTableNameForCharts(macro, start, end);
                StringBuffer buf = new StringBuffer();
                boolean first = true;
                for(String table : tableList) {
                    if(!first) {
                        buf.append("|");
                    }
                    first = false;
                    buf.append(table);
                }
                return buf.toString();
            }
        }
        String[] tableList = dbc.findTableName(macro,current,current);
        return tableList[0];
    }
    public String toString() {
        try {
          HashMap<String, String> macroList = findMacros(query);
          for(Entry<String, String> entry : macroList.entrySet()) {
            String mkey = entry.getKey();
            String value = entry.getValue();
            if(value.contains("|")) {
              StringBuffer buf = new StringBuffer();
              String[] tableList = value.split("\\|");
              boolean first = true;
              for(String table : tableList) {
                String newQuery = query.replace("["+mkey+"]", table);
                if(!first) {
                  buf.append(" union ");
                }
                buf.append("(");
                buf.append(newQuery);
                buf.append(")");
                first = false;
              }
              query = buf.toString();
            } else {
              log.debug("replacing:"+mkey+" with "+macroList.get(mkey));
              query = query.replace("["+mkey+"]", macroList.get(mkey));
            }
          }
        } catch(SQLException ex) {
            log.error(query);
            log.error(ex.getMessage());
        }
        return query;
    }

}
