/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.1 (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.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * 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.queplix.core.integrator.util;

import com.queplix.core.client.app.vo.EntityData;
import com.queplix.core.client.app.vo.EntityElement;
import com.queplix.core.integrator.ActionContext;
import com.queplix.core.integrator.entity.EntitySerializeHelper;
import com.queplix.core.integrator.security.LogonSession;
import com.queplix.core.utils.StringHelper;
import com.queplix.core.utils.log.AbstractLogger;
import com.queplix.core.utils.log.Log;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class ReportSerializeHelper {

    private static final AbstractLogger logger = Log.getLog(
            ReportSerializeHelper.class);

    public static final String SERIALIZED_REPORTS_FIELD_ID = "body";

    public static final String FIELDS_SET_AND_FILTERS_DIV = "$";
    public static final String ENTITIES_DIV = ";";
    public static final String FIELDS_DIV = ":";

    public static AdhocReport deSerializeReport(String serializedReport,
                                                LogonSession ls,
                                                ActionContext actx) {
        List<EntityElement> reportFields = new ArrayList<EntityElement>();
        List<EntityData> filters = new ArrayList<EntityData>();
        if(!StringHelper.isEmpty(serializedReport)) {
            int divIndex = serializedReport.indexOf(
                    ReportSerializeHelper.FIELDS_SET_AND_FILTERS_DIV);
            if(divIndex > 0) {
                String serializedFieldsSet = serializedReport.substring(0,
                        divIndex);
                reportFields.addAll(deSerializeFieldsSet(serializedFieldsSet));
                String serializedFilters = serializedReport.substring(
                        divIndex + 1);
                filters.addAll(EntitySerializeHelper.deSerializeEntities(
                        serializedFilters, ls, actx));
            }
        }
        return new AdhocReport(reportFields, filters);
    }

    public static String serializeReport(List<EntityElement> fields,
                                         List<EntityData> filters,
                                         LogonSession ls, ActionContext actx) {
        String serializedFieldsSet = serializeFieldsSet(fields);
        String serializedFilters = EntitySerializeHelper.serialize(filters, ls,
                actx);
        return serializedFieldsSet + FIELDS_SET_AND_FILTERS_DIV
                + serializedFilters;
    }

    private static String serializeFieldsSet(List<EntityElement> fields) {
        String ret = "";
        for(EntityElement field : fields) {
            ret += field.getFormId() + FIELDS_DIV + field.getElementId()
                    + FIELDS_DIV + field.getElementCaption() + ENTITIES_DIV;
        }
        return ret;
    }

    private static List<EntityElement> deSerializeFieldsSet(
            String serializedFields) {
        List<EntityElement> ret = new LinkedList<EntityElement>();
        if(!StringHelper.isEmpty(serializedFields)) {
            String[] entities = serializedFields.split(ENTITIES_DIV);
            for(String entity : entities) {
                String[] formFieldAndCaption = entity.split(FIELDS_DIV);
                if(formFieldAndCaption.length >= 3) {
                    ret.add(new EntityElement(formFieldAndCaption[0],
                            formFieldAndCaption[1], formFieldAndCaption[2]));
                }
            }
        }
        return ret;
    }

}