/*----------------------------------------------------------------------------
Copyright (c)2000 TogetherSoft Corporation. Patents pending. All rights reserved.
----------------------------------------------------------------------------*/
package com.togethersoft.modules.patterns.JAVA.CLASS.HP_E_Speak.Client.code;

import  com.togethersoft.openapi.sci.*;
import  com.togethersoft.openapi.sci.enum.SciClassEnumeration;
import  com.togethersoft.openapi.sci.enum.SciInheritanceEnumeration;

import  com.togethersoft.openapi.util.propertyMap.PropertyMap;

import com.togethersoft.modules.patterns.JAVA.CLASS.HP_E_Speak.Client.CompositeSciTemplate;
import com.togethersoft.modules.patterns.JAVA.CLASS.HP_E_Speak.Client.ClientProperty;
/**
 * @author TogetherSoft
 */
class ClientSrvGetterTemplate extends CompositeSciTemplate {

        /*
         * Defaults.
         */
        private static final String DEFAULT_SERVICE_NAME       = "net.espeak.jesi.ESService";
//        private static final String DEFAULT_SERVICE_NAME_SHORT = "ESService";

        public ClientSrvGetterTemplate(PropertyMap properties) {
                super(properties);

                addTemplate(new ClientVocFindTemplate(properties));
                addTemplate(new ClientSrvQueryTemplate(properties));
                addTemplate(new ClientSrvFindTemplate(properties));
                }

        public boolean prepare( SciObject target) {

                /*
                 * Provide initial value of ESService interface name.
                 */
                if (!exists(DEFAULT_SERVICE_NAME)) {
                        setErrorMessage("Interface " + DEFAULT_SERVICE_NAME + " was not found," +
                                        " add eslib.jar library to the classpath or as the project import root." );
                        return false;
                        }

                String esServiceName = DEFAULT_SERVICE_NAME;
                SciPackage parentPackage = null;

                if (target instanceof SciClass) {
                        // check target.
                        parentPackage = ((SciClass) target).getContainingPackage();
                        if (isESServiceInterface((SciClass) target)) {
                                esServiceName = ((SciElement) target).getQualifiedName();
                                }
                        }
                else if (target instanceof SciPackage) {
                        // check current package.
                        parentPackage = (SciPackage) target;
                        for(SciClassEnumeration classes = ((SciPackage) target).classes(); classes.hasMoreElements();) {
                                SciClass clazz = classes.nextSciClass();

                                if (isESServiceInterface(clazz)) {
                                        esServiceName = clazz.getQualifiedName();
                                        break;
                                        }
                                }
                        }


                setPropertyValue(ClientProperty.SERVICE_INTERFACE_NAME, esServiceName);
                return super.prepare(target);
                }

        public SciObject generate(SciObject target) {

                SciClass clazz = (SciClass) target;

                /*
                 * Add import statement for Service interface.
                 */
                if (!DEFAULT_SERVICE_NAME.equals(getPropertyValue(ClientProperty.SERVICE_INTERFACE_NAME))) {
                        // DEFAULT_SERVICE_NAME already imported.

                        SciJavaImport javaImport = getSciFactory().newJavaImport();
                        javaImport.setImportText(getStringPropertyValue(ClientProperty.SERVICE_INTERFACE_NAME));
                        clazz.getContainingFile().getJavaImportList().paste(javaImport, null, true);
                        }

                /*
                 * Generate getter.
                 */
                SciOperation operation = getSciFactory().newOperation();
                operation.setName("getESService");
                operation.getReturnType().setText(getStringPropertyValue(ClientProperty.SERVICE_INTERFACE_NAME));

                /*
                 * Generate getter code.
                 */
                String ifStatementCode     = "if (this." + ClientAttribute.GLOBAL_SERVICE + " == null) {\n}\n";
                String returnStatementCode = "return this." + ClientAttribute.GLOBAL_SERVICE + ";";

                SciIfStatement conditionStatement  = null;
                SciReturnStatement returnStatement = null;

                operation = (SciOperation) clazz.paste(operation, null, true);

                try {
                        conditionStatement = (SciIfStatement) getSciGenericFactory().newStatement(ifStatementCode);
                        returnStatement    = (SciReturnStatement) getSciGenericFactory().newStatement(returnStatementCode);

                        conditionStatement = (SciIfStatement) operation.getBody().paste(conditionStatement, null, true);
                        returnStatement    = (SciReturnStatement) operation.getBody().paste(returnStatement, null, true);
                        }
                catch(SciGenericFactoryException sciException) {
                        System.out.println("exception during creating statements : " + sciException);
                        }

                super.generate(conditionStatement.getThenCodeBlock());

                /*
                 * Generate service attribute.
                 */
                SciAttribute attribute = getSciFactory().newAttribute();
                attribute.setName(ClientAttribute.GLOBAL_SERVICE);
                attribute.getType().setText(getStringPropertyValue(ClientProperty.SERVICE_INTERFACE_NAME));
                attribute = (SciAttribute) clazz.paste(attribute, null, true);

                return clazz;
                }

        public boolean canGenerate() {
                if (getPropertyValue(ClientProperty.SERVICE_INTERFACE_NAME) == null) {
                        setErrorMessage("Specify valid ES Service Interface.");
                        return false;
                        }

                if (!exists(getStringPropertyValue(ClientProperty.SERVICE_INTERFACE_NAME))) {
                        setErrorMessage("Specify existing ES Service Interface.");
                        return false;
                        }

                return super.canGenerate();
                }

        protected boolean isESServiceInterface(SciClass clazz) {

                if ((clazz != null) &&
                    (clazz.hasProperty(SciProperty.INTERFACE))) {

                        SciClass esServiceClass = getSciModel().findClass(getLanguage(), DEFAULT_SERVICE_NAME);
                        if (esServiceClass == null) {
                                return false;
                                }

                        // check "extends" part.
                        SciInheritanceList inheritanceList = clazz.getExtendsList();

                        for(SciInheritanceEnumeration inheritances = inheritanceList.inheritances(); inheritances.hasMoreElements();) {
                                SciInheritance inheritance = inheritances.nextSciInheritance();

                                if (esServiceClass.equals(inheritance.getReferencedElement())) {
                                        return true;
                                        }
                                }
                        }

                return false;
                }


        protected boolean exists(String qualifiedName) {
                return getSciModel().findClass(getLanguage(), qualifiedName) != null;
                }
        }


