import DefinitionPattern from './DefinitionPattern';
import {copy} from './common';
import attributeGetter from '../SparqlAttribute/getter';
import  {ARITHMETIC_SYMBOL} from './arithmetic_filter';
import sparqljs from 'sparqljs';

export enum AGGREGATE_KEYORD {
    SUM = 'SUM',
    AVG = 'AVG',
    COUNT = 'COUNT',
    MIN = 'MIN',
    MAX = 'MAX',
}

export function aggregate_filter(aggregate_keyword: AGGREGATE_KEYORD, arithmetic_symbol: ARITHMETIC_SYMBOL, reference: string, definition: DefinitionPattern, json_pointer: string, value: string |  number) {
    let incremented_definition = copy(definition);
    // Find the relevant definition in case of nesting
    let {attribute, nestedPath} = {...attributeGetter(reference, json_pointer)};
    let pointerToDefinition = incremented_definition;
    nestedPath.forEach((path) => {
        pointerToDefinition = pointerToDefinition.subQuery[path];
    })
    let attributeName = '';
    if (attribute.reference !== undefined  && attribute.reference.length > 0) {
        attributeName = '?' + attribute.name + '_pKey'
    } else {
        attributeName = '?' + attribute.name
    }
    let aggregate = 
    {
        type: 'operation',
        operator: arithmetic_symbol,
        args: [
            {
                type: 'aggregate',
                aggregation: aggregate_keyword,
                expression: attributeName,
                distinct: true
            },
            // If the value is a number, assume it is a decimal
            (typeof value === 'number') ? `"${value}"^^http://www.w3.org/2001/XMLSchema#decimal` :  `"${value}"`
        ]
    };
    pointerToDefinition.query.having = pointerToDefinition.query.having || [];

    (<sparqljs.Expression[]>pointerToDefinition.query.having).push(<sparqljs.Expression>aggregate);
    return incremented_definition;
}

export default aggregate_filter;
