import SparqlObject from './SparqlObject'
import SparqlAttribute from '../SparqlAttribute/SparqlAttribute'
import {Type} from '../Core/types'
import {AttributeNestedI} from './types'
import jsonpointer from 'json-pointer'
import merge from '../common/merge_object'

export function jsonBindings(this: SparqlObject) {
    let object = objectify.apply(this);
    let jsonBindings = `(concat('`;
    jsonBindings += parseJsonRepresentation(object);
    jsonBindings += `') AS ?object)`;
    return jsonBindings;
}

export function bindings(this: SparqlObject) {
    return this.attributes
        .filter((attribute) => {
            return attribute.type !== Type.OBJECT;
        })
        .map((attribute) => {
            return attribute.binding;
        })
        .join(' ');
}

function objectify(this: SparqlObject) {
    let objectRepresentation: { [key: string]: AttributeNestedI } = {};
    // let tmp_attributes = this.attributes
    //     .map((attribute) => {
    //         let tmp_attribute = Object.create(attribute) as SparqlAttribute;
    //         tmp_attribute = Object.assign(tmp_attribute, attribute);
    //         let tmp_path: string[] = Array<string>(attribute.path.length * 2 - 1);
    //         for (let index = 0; index < tmp_path.length; index++) {
    //             if (index % 2 === 0) {
    //                 // Even index
    //                 // tmp_path[index] = attribute.path[index / 2];
    //             } else {
    //                 // Odd index
    //                 tmp_path[index] = "nest";
    //             }
    //         }
    //         // tmp_attribute.path = tmp_path;
    //         return tmp_attribute;
    //     });
    // tmp_attributes.forEach((attribute) => {
    //     // let pointer = attribute.pointer;
    //     // if (jsonpointer.has(objectRepresentation, pointer)) {
    //     //     let previous = jsonpointer.get(objectRepresentation, pointer);
    //     //     jsonpointer.set(objectRepresentation, pointer, merge(previous, attribute));
    //     // } else {
    //     //     jsonpointer.set(objectRepresentation, pointer, attribute);
    //     // }
    // })
    return objectRepresentation;
}


function parseJsonRepresentation(object: { [key: string]: AttributeNestedI }) {
    let representation = '';
    representation += '{';
    representation += Object.keys(object).map((key) => {
        let attributeNested = object[key];
        let tmpRepresentation: string;

        let subRepresentation = '"' + attributeNested.binding.substring(1) + '":'; // Remove the '?'
        if (attributeNested.type === Type.OBJECT && attributeNested.nest) {
            tmpRepresentation = parseJsonRepresentation(attributeNested.nest);
        } else {
            tmpRepresentation = `"',${attributeNested.binding},'"`;
        }
        if (attributeNested.arrayable) {
            subRepresentation += `[',group_concat(distinct concat(' ${tmpRepresentation} ');separator=','),']`
        } else {
            subRepresentation += tmpRepresentation;
        }
        return subRepresentation;
    })
        .join(',')
    representation += '}';
    return representation;
}



export default jsonBindings;