
import SparqlTask from '../Core/SparqlTask'
import { pathToBinding } from '../SparqlObject/common';
import SparqlAttribute from '../SparqlAttribute/SparqlAttribute';
import sparqljs from 'sparqljs';


export function jsonRepresentation(reference: string, alias: string, path: string[] = [], asString = false) {
    let model = SparqlTask.sparqlObjects[reference];
    let concat_operation: sparqljs.OperationExpression = {
        type: 'operation',
        operator: 'concat',
        args: []
    };
    let representation = `(CONCAT ('{', `;
    concat_operation.args.push(<sparqljs.Expression>('{'));
    representation += model.attributes.map((attribute) => {
        concat_operation.args.push(<sparqljs.Expression>('\'"' + attribute.name + '":'));
        let subRepresentation = '\'"' + attribute.name + '":'; // Remove the '?'
        if (attribute.arrayable) {
            concat_operation.args.push(<sparqljs.Expression>(`[`));

            let concat_aggregate: sparqljs.AggregateExpression = {
                type: 'aggregate',
                aggregation: 'group_concat',
                distinct: true,
                separator: ',',
                expression: [<sparqljs.Expression>(expression(attribute))]
            };
            concat_operation.args.push(concat_aggregate);
            concat_operation.args.push(<sparqljs.Expression>(`]`));
            subRepresentation += `[',GROUP_CONCAT(DISTINCT CONCAT( ${expression(attribute)});separator=','),']'`
        } else {
            concat_operation.args.push(<sparqljs.Expression>(`',${expression(attribute)}`));
            subRepresentation += `',${expression(attribute)}`
        }
        return subRepresentation;
    })
        .join(',",",')
    let _jsonRepresentation: sparqljs.VariableExpression = {
        expression: concat_operation,
        variable: <sparqljs.Term>pathToBinding([...path, alias || model.reference])
    };
    representation += `,'}') AS ${pathToBinding([...path, alias || model.reference])})`;
    if (asString) {
        return representation;
    } else {
        return _jsonRepresentation
    }
}

export function groupBy(reference: string, path: string[] = []) {
    let model = SparqlTask.sparqlObjects[reference];
    let groupBy = model.attributes.filter((attribute) => {
        return !attribute.arrayable;
    }).map((attribute) => {
        return pathToBinding([...path, attribute.name])
    }).join(' ');
    return groupBy;
}

function expression(attribute: SparqlAttribute) {
    if (attribute.type === 'OBJECT') {
        return pathToBinding([attribute.name])
    } else {
        return '\'"\',' + pathToBinding([attribute.name]) + ',\'"\''
    }
}