package org.saiku.service.olap.totals.aggregators;

import mondrian.util.Format;
import org.olap4j.Cell;
import org.olap4j.metadata.Measure;
import org.saiku.olap.util.SaikuProperties;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public abstract class TotalAggregator {
  private static final Map<String, TotalAggregatorFactory> all;

  private static interface TotalAggregatorFactory {
    TotalAggregator create();
  }

  static {
    Map<String, TotalAggregatorFactory> tmp = new HashMap<>();

    tmp.put( "sum", new TotalAggregatorFactory() {
      public TotalAggregator create() {
        return new SumAggregator( null );
      }      
    });

    tmp.put( "max", new TotalAggregatorFactory() {
      public TotalAggregator create() {
        return new MaxAggregator( null );
      }      
    });

    tmp.put( "min", new TotalAggregatorFactory() {
      public TotalAggregator create() {
        return new MinAggregator( null );
      }      
    });

    tmp.put( "avg", new TotalAggregatorFactory() {
      public TotalAggregator create() {
        return new AvgAggregator( null );
      }      
    });

    all = Collections.unmodifiableMap( tmp );
  }

  private String formattedValue;
  final Format format;

  TotalAggregator(Format format) {
    this.format = format;
  }

  public void addData( Cell cell ) {
    try {
      // FIXME - maybe we should try to do fetch the format here, but seems to cause some issues? infinite loop? make
      // sure we try this only once to override existing format?
      //		if (format == null) {
      //			String formatString = (String) cell.getPropertyValue(Property.StandardCellProperty.FORMAT_STRING);
      //			this.format = Format.get(formatString, SaikuProperties.locale);
      //
      //		}
      Object value = cell.getValue();
      if ( value instanceof Number ) {
        double doubleVal;

        doubleVal = cell.getDoubleValue();
        addData( doubleVal );
      }
    } catch ( Exception e ) {
      throw new RuntimeException( e );
    }

  }

  protected abstract void addData( double data );

  protected abstract Double getValue();

  public abstract TotalAggregator newInstance( Format format, Measure measure );

  public String getFormattedValue() {
    if ( formattedValue != null ) {
      return formattedValue;
    } else {
      Double value = getValue();
      if ( value != null ) {
        return format.format( value );
      }
      return "";
    }
  }

  public void setFormattedValue( String formattedValue ) {
    this.formattedValue = formattedValue;
  }

  public TotalAggregator newInstance() {
    return newInstance( "" );
  }

  private TotalAggregator newInstance(String formatString) {
    return newInstance( new Format( formatString, SaikuProperties.locale ), null );
  }

  public static TotalAggregator newInstanceByFunctionName( final String functionName ) {
    return all.get( functionName ).create( );
  }
}
@@ -2901,24 +2901,97 @@
 ionName ) %7B%0A
+    if(functionName.equals(%22not%22))%7B%0A     return null;%0A    %7D%0A    else %7B%0A  
     return a
@@ -2997,17 +2997,16 @@
 all.get(
- 
 function
@@ -3009,17 +3009,16 @@
 tionName
- 
 ).create
@@ -3018,17 +3018,22 @@
 .create(
- 
 );%0A
+    %7D%0A
   %7D%0A%7D

fix switching off totals