/*
 * Copyright 2011 Damien Bourdette
 *
 * Licensed 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 com.github.dbourdette.otto.web.form;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;

import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.Interval;

import com.github.dbourdette.otto.graph.Graph;
import com.github.dbourdette.otto.source.DBSource;
import com.github.dbourdette.otto.source.DefaultGraphParameters;
import com.github.dbourdette.otto.web.util.Pair;
import com.mongodb.DBObject;

/**
 * @author damien bourdette
 * @version \$Revision$
 */
public class GraphForm {
    @NotNull
    private GraphPeriod period;

    public String sumColumn;

    public String splitColumn;

    public GraphForm() {
        period = GraphPeriod.RECENT;
    }

    public Interval getInterval() {
        return period.getInterval();
    }

    public void fillWithDefault(DefaultGraphParameters defaultParameters, HttpServletRequest request) {
        Map<String, String> map = request.getParameterMap();

        if (!map.containsKey("splitColumn")) {
            setSplitColumn(defaultParameters.getSplitColumn());
        }

        if (!map.containsKey("sumColumn")) {
            setSumColumn(defaultParameters.getSumColumn());
        }
    }

    public List<Pair> getValues(DBSource source) {
        Graph graph = buildGraph(source);

        List<Pair> values = new ArrayList<Pair>();

        for (String column : graph.getColumnTitles()) {
            values.add(new Pair(column, graph.getSum(column)));
        }

        return values;
    }

    public List<Pair> getCounts(DBSource source) {
        String temp = sumColumn;

        sumColumn = null;

        List<Pair> pairs = getValues(source);

        sumColumn = temp;

        return pairs;
    }

    public Graph buildGraph(DBSource source) {
        Graph graph = new Graph();

        Interval interval = getInterval();

        graph.setRows(interval, Duration.standardMinutes(getStepInMinutes()));

        Iterator<DBObject> events = source.findEvents(interval);

        while (events.hasNext()) {
            DBObject event = events.next();

            String columnName = getSplitColumnName(source, event);

            graph.ensureColumnsExists(columnName);

            Date date = (Date) event.get("date");

            if (StringUtils.isEmpty(getSumColumn())) {
                graph.increaseValue(columnName, new DateTime(date));
            } else {
                Object value = event.get(getSumColumn());

                if (value instanceof Integer) {
                    graph.increaseValue(columnName, new DateTime(date), (Integer) value);
                } else {
                    graph.increaseValue(columnName, new DateTime(date));
                }
            }
        }

        if (graph.getColumnCount() == 0) {
            graph.ensureColumnExists("no data");
        }

        return graph;
    }

    public int getStepInMinutes() {
        return period.getStepInMinutes();
    }

    public String getSumColumn() {
        return sumColumn;
    }

    public void setSumColumn(String sumColumn) {
        this.sumColumn = sumColumn;
    }

    public String getSplitColumn() {
        return splitColumn;
    }

    public void setSplitColumn(String splitColumn) {
        this.splitColumn = splitColumn;
    }

    public GraphPeriod[] getPeriods() {
        return GraphPeriod.values();
    }

    public GraphPeriod getPeriod() {
        return period;
    }

    public void setPeriod(GraphPeriod period) {
        this.period = period;
    }

    private String getSplitColumnName(DBSource source, DBObject event) {
        if (StringUtils.isEmpty(getSplitColumn())) {
            return source.getName();
        }

        Object value = event.get(getSplitColumn());

        if (value == null) {
            return source.getName();
        }

        return value.toString();
    }
}

@@ -4403,20 +4403,17 @@
 isEmpty(
-getS
+s
 plitColu
@@ -4410,26 +4410,24 @@
 (splitColumn
-()
 )) %7B%0A       
@@ -4459,32 +4459,194 @@
 e();%0A        %7D%0A%0A
+        StringBuilder result = new StringBuilder();%0A%0A        String%5B%5D columns = StringUtils.split(splitColumn, %22,%22);%0A%0A        for (String column : columns) %7B%0A    
         Object v
@@ -4666,28 +4666,22 @@
 get(
-getSplitC
+c
 olumn
-()
 );%0A%0A
+    
     
@@ -4694,17 +4694,17 @@
  (value 
-=
+!
 = null) 
@@ -4721,32 +4721,163 @@
     
-return source.getName();
+    if (result.length() != 0) %7B%0A                    result.append(%22 - %22);%0A                %7D%0A%0A                result.append(value.toString());%0A            %7D
 %0A   
@@ -4899,21 +4899,22 @@
  return 
-value
+result
 .toStrin

Split on multiple columns