/*
 * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. licenses this file to you under the Apache License,
 * Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * 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 org.wso2.carbon.siddhi.editor.core.util.designview.designgenerator.generators.attributesselection;

import org.wso2.carbon.siddhi.editor.core.util.designview.beans.configs.siddhielements.attributesselection.AttributesSelectionConfig;
import org.wso2.carbon.siddhi.editor.core.util.designview.beans.configs.siddhielements.attributesselection.SelectedAttribute;
import org.wso2.carbon.siddhi.editor.core.util.designview.constants.AttributeSelection;
import org.wso2.carbon.siddhi.editor.core.util.designview.designgenerator.factories.AttributesSelectionConfigFactory;
import org.wso2.carbon.siddhi.editor.core.util.designview.utilities.ConfigBuildingUtilities;
import org.wso2.siddhi.query.api.SiddhiApp;
import org.wso2.siddhi.query.api.execution.query.selection.OutputAttribute;
import org.wso2.siddhi.query.api.expression.AttributeFunction;
import org.wso2.siddhi.query.api.expression.Variable;

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

/**
 * Generates AttributesSelectionConfig with given Siddhi elements
 */
public class AttributesSelectionConfigGenerator {
    private String siddhiAppString;

    public AttributesSelectionConfigGenerator(String siddhiAppString) {
        this.siddhiAppString = siddhiAppString;
    }

    /**
     * Generates config object with the given list of selected attributes
     * @param outputAttributes      List of selected attributes
     * @return                      Config object with selected attributes
     */
    public AttributesSelectionConfig generateAttributesSelectionConfig(List<OutputAttribute> outputAttributes) {
        List<SelectedAttribute> selectedAttributes = new ArrayList<>();
        AttributesSelectionConfigFactory attributesSelectionConfigFactory = new AttributesSelectionConfigFactory();
        if (!outputAttributes.isEmpty()) {
            for (OutputAttribute outputAttribute : outputAttributes) {
                selectedAttributes.add(generateSelectedAttributeConfig(outputAttribute));
            }
            return attributesSelectionConfigFactory.getAttributesSelectionConfig(selectedAttributes);
        }
        // Empty outputAttributes after a successful compilation of Siddhi app means "select *"
        return attributesSelectionConfigFactory.getAttributesSelectionConfig(AttributeSelection.VALUE_ALL);
    }

    /**
     * Generates SelectedAttribute object, for the given OutputAttribute, which is a selection of a Siddhi Attribute
     * @param outputAttribute       A selected attribute
     * @return                      SelectedAttribute object
     */
    private SelectedAttribute generateSelectedAttributeConfig(OutputAttribute outputAttribute) {
        String[] splitString = ConfigBuildingUtilities.getDefinition(outputAttribute, siddhiAppString).split(" as ");
        if (splitString.length == 1) {
            return new SelectedAttribute(splitString[0].trim(), "");
        }
        return new SelectedAttribute(splitString[0].trim(), splitString[1].trim());
    }
}

@@ -1566,16 +1566,139 @@
 ion.
-Variable
+Expression;%0Aimport org.wso2.siddhi.query.api.expression.Variable;%0Aimport org.wso2.siddhi.query.api.expression.constant.TimeConstant
 ;%0A%0Ai
@@ -2562,24 +2562,26 @@
 gFactory();%0A
+%0A%0A
         if (
@@ -3453,24 +3453,299 @@
 ttribute) %7B%0A
+        String rename = %22%22;%0A        if (outputAttribute.getRename() != null) %7B%0A            rename = outputAttribute.getRename();%0A        %7D%0A         String name = generateExpressionName(outputAttribute.getExpression());%0A%0A        return new SelectedAttribute(name, rename);%0A%0A//
         Stri
@@ -3846,24 +3846,26 @@
 it(%22 as %22);%0A
+//
         if (
@@ -3887,24 +3887,26 @@
 gth == 1) %7B%0A
+//
             
@@ -3962,16 +3962,18 @@
 ), %22%22);%0A
+//
         
@@ -3966,32 +3966,34 @@
 %22);%0A//        %7D%0A
+//
         return n
@@ -4065,11 +4065,1014 @@
 );%0A    %7D
+%0A%0A    private String generateExpressionName(Expression expression) %7B%0A        if (expression instanceof Variable) %7B%0A            Variable variable = (Variable) expression;%0A            String attributeName = variable.getAttributeName();%0A            if (variable.getStreamId() != null) %7B%0A                attributeName = variable.getStreamId() + %22.%22 + attributeName;%0A            %7D%0A            return attributeName;%0A        %7D%0A        if (expression instanceof AttributeFunction) %7B%0A            AttributeFunction attributeFunction = (AttributeFunction) expression;%0A            List%3CString%3E parameterList = new ArrayList%3C%3E();%0A            for (Expression parameter : attributeFunction.getParameters()) %7B%0A                parameterList.add(generateExpressionName(parameter));%0A            %7D%0A            return String.format(%22%25s(%25s)%22, attributeFunction.getName(), String.join(%22 , %22, parameterList));%0A        %7D%0A        // TODO add more%0A        throw new IllegalArgumentException(%22Type of Expression is unknown%22);%0A    %7D
 %0A%7D%0A

Improve attribute selection config generator