/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF 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.netbeans.modules.payara.jakartaee;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.modules.payara.tooling.data.PayaraVersion;
import org.netbeans.modules.payara.tooling.server.config.JavaEEProfile;
import org.netbeans.modules.payara.tooling.server.config.JavaSEPlatform;
import org.netbeans.modules.payara.tooling.server.config.ModuleType;
import static org.netbeans.modules.payara.tooling.server.config.ModuleType.EJB;
import static org.netbeans.modules.payara.tooling.server.config.ModuleType.RAR;
import org.netbeans.modules.payara.tooling.utils.ServerUtils;
import org.netbeans.api.j2ee.core.Profile;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.java.classpath.JavaClassPathConstants;
import org.netbeans.api.java.platform.JavaPlatform;
import org.netbeans.api.java.project.JavaProjectConstants;
import org.netbeans.api.java.project.classpath.ProjectClassPathModifier;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.api.project.SourceGroup;
import org.netbeans.api.project.libraries.Library;
import org.netbeans.modules.payara.spi.PayaraModule;
import org.netbeans.modules.payara.spi.ServerUtilities;
import org.netbeans.modules.payara.tooling.data.PayaraServer;
import org.netbeans.modules.j2ee.deployment.common.api.J2eeLibraryTypeProvider;
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule;
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule.Type;
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
import org.netbeans.modules.j2ee.deployment.plugins.spi.J2eePlatformImpl2;
import org.netbeans.modules.j2ee.deployment.plugins.spi.support.LookupProviderSupport;
import org.netbeans.modules.javaee.specs.support.api.JaxRpc;
import org.netbeans.modules.javaee.specs.support.api.JaxWs;
import org.netbeans.modules.javaee.specs.support.spi.JaxRsStackSupportImplementation;
import org.netbeans.modules.websvc.wsstack.api.WSStack;
import org.netbeans.modules.websvc.wsstack.spi.WSStackFactory;
import org.netbeans.spi.project.libraries.LibraryImplementation;
import org.openide.filesystems.*;
import org.openide.util.ImageUtilities;
import org.openide.util.Lookup;
import org.openide.util.RequestProcessor;
import org.openide.util.Utilities;
import org.openide.util.lookup.Lookups;
    
/**
 *
 * @author Ludo, Tomas Kraus
 */
public class Hk2JavaEEPlatformImpl extends J2eePlatformImpl2 {
    
    /** Deployment manager. */
    private final Hk2DeploymentManager dm;

    /** Payara library. */
    private final LibraryImplementation lib = new J2eeLibraryTypeProvider().createLibrary();

    /** Payara library storage. */
    private final LibraryImplementation[] libraries = { lib };

    /** NetBeans JavaSE platforms. */
    private final String[] platforms;

    /** NetBeans JavaEE profiles. */
    private final Profile[] profiles;

    /** NetBeans JavaEE module types. */
    private final J2eeModule.Type[] types;

    /** NetBeans JavaEE platform display name. */
    private final String displayName;

    /** NetBeans JavaEE library name. */
    private final String libraryName;

    /** Payara JavaEE platform lookup key. */
    private final String lookupKey;

    private FileChangeListener fcl;

    /** Keep local Lookup instance to be returned by getLookup method. */
    private final Lookup lkp;

    /** Jersey Library support. */
    private final Hk2LibraryProvider libraryProvider;

    ////////////////////////////////////////////////////////////////////////////
    // Static methods                                                         //
    ////////////////////////////////////////////////////////////////////////////

    /**
     * Constructor helper to initialize local Lookup instance.
     * <p/>
     * @return Local Lookup instance.
     */
    private Lookup initLocalLookup() {
        final String gfRootStr = dm.getProperties().getPayaraRoot();
        final WSStack<JaxWs> wsStack = WSStackFactory.createWSStack(JaxWs.class,
                new Hk2JaxWsStack(gfRootStr, this), WSStack.Source.SERVER);
        final WSStack<JaxRpc> rpcStack = WSStackFactory.createWSStack(JaxRpc.class,
                new Hk2JaxRpcStack(gfRootStr), WSStack.Source.SERVER);
        final PayaraServer server = dm.getCommonServerSupport().getInstance();
        final Lookup baseLookup = Lookups.fixed(
                gfRootStr, new JaxRsStackSupportImpl(), wsStack, rpcStack,
                server, new Hk2JpaSupportImpl(server));
        return LookupProviderSupport.createCompositeLookup(
                baseLookup, lookupKey);
    }

    /**
     * Map Payara tooling SDK JavaSE platforms to NetBeans JavaSE platforms.
     * <p/>
     * @param sdkPlatforms Payara tooling SDK JavaSE platforms.
     * @return Array of NetBeans JavaSE platforms containing known Payara
     *         tooling SDK JavaSE platforms.
     */
    @SuppressWarnings("ValueOfIncrementOrDecrementUsed")
    public static String[] nbJavaSEProfiles(
            final Set<JavaSEPlatform> sdkPlatforms) {
        final int size = sdkPlatforms != null ? sdkPlatforms.size() : 0;
        String[] platforms = new String[size];
        if (size > 0) {
            int index = 0;
            for (JavaSEPlatform platform : sdkPlatforms) {
                platforms[index++] = platform.toString();
            }
        }
        return platforms;
    }
            
    
    /**
     * Map Payara tooling SDK JavaEE profiles to NetBeans JavaEE profiles.
     * <p/>
     * @param sdkProfiles Payara tooling SDK JavaEE profiles.
     * @return Array of NetBeans JavaEE profiles containing known Payara
     *         tooling SDK JavaEE profiles.
     */
    @SuppressWarnings("ValueOfIncrementOrDecrementUsed")
    public static Profile[] nbJavaEEProfiles(
            final Set<JavaEEProfile> sdkProfiles) {
        final int sdkSize = sdkProfiles != null ? sdkProfiles.size() : 0;
        int size = sdkSize;
        // Shrink output array size for unsupported JavaEE profiles.
        for (JavaEEProfile sdkProfile : sdkProfiles) switch(sdkProfile) {
            case v1_2: size--;
        }
        Profile[] profiles;
        if (sdkSize > 0) {
            profiles = new Profile[size];
            int index = 0;
            // JavaEE 1.2 should be ignored.
            for (JavaEEProfile sdkProfile : sdkProfiles) switch(sdkProfile) {
                case v1_3:     profiles[index++] = Profile.J2EE_13;
                               break;
                case v1_4:     profiles[index++] = Profile.J2EE_14;
                               break;
                case v1_5:     profiles[index++] = Profile.JAVA_EE_5;
                               break;
                case v1_6_web: profiles[index++] = Profile.JAVA_EE_6_WEB;
                               break;
                case v1_6:     profiles[index++] = Profile.JAVA_EE_6_FULL;
                               break;
                case v1_7_web: profiles[index++] = Profile.JAVA_EE_7_WEB;
                               break;
                case v1_7:     profiles[index++] = Profile.JAVA_EE_7_FULL;
                               break;
                case v1_8_web: profiles[index++] = Profile.JAVA_EE_8_WEB;
                               break;
                case v1_8:     profiles[index++] = Profile.JAVA_EE_8_FULL;
                               break;
            }
        } else {
            profiles = new Profile[0];
        }
        return profiles;
    }

    /**
     * Map Payara tooling SDK JavaEE module types to NetBeans JavaEE
     * module types.
     * <p/>
     * @param sdkModule Payara tooling SDK JavaEE module types.
     * @return Array of NetBeans JavaEE module types containing known Payara
     *         tooling SDK JavaEE module types.
     */
    @SuppressWarnings("ValueOfIncrementOrDecrementUsed")
    public static J2eeModule.Type[] nbModuleTypes(
            final Set<ModuleType> sdkModuleTypes) {
        final int size = sdkModuleTypes != null ? sdkModuleTypes.size() : 0;
        J2eeModule.Type[] types = new J2eeModule.Type[size];
        if (size > 0) {
            int index = 0;
            for (ModuleType sdkType : sdkModuleTypes) switch(sdkType) {
                case EAR: types[index++] = J2eeModule.Type.EAR;
                          break;
                case EJB: types[index++] = J2eeModule.Type.EJB;
                          break;
                case CAR: types[index++] = J2eeModule.Type.CAR;
                          break;
                case RAR: types[index++] = J2eeModule.Type.RAR;
                          break;
                case WAR: types[index++] = J2eeModule.Type.WAR;
                          break;
            }
        }
        return types;
    }

    /**
     * Create {@see Set} of {@see String} objects from array of supported
     * JavaSE platform objects.
     * <p>
     * @param platforms Array of supported JavaSE platforms.
     * @return Newly created set of supported JavaSE platforms.
     */
    Set<String> platformsSetFromArray(final String[] platforms) {
        final int size = platforms != null ? platforms.length : 0;
        Set<String> platformSet = new HashSet<>(size);
        for (int i = 0; i < size; i++) {
            platformSet.add(platforms[i]);
        }
        return platformSet;
    }

    /**
     * Create {@see Set} of {@see Profile} objects from array of those objects.
     * <p>
     * @param profiles Array of NetBeans JavaEE profiles.
     * @return Newly created set of NetBeans JavaEE profiles from array.
     */
    Set<Profile> profilesSetFromArray(final Profile[] profiles) {
        final int size = profiles != null ? profiles.length : 0;
        final Set<Profile> profileSet = new HashSet<>(size);
        for (int i = 0; i < size; i++) {
            profileSet.add(profiles[i]);
        }
        return profileSet;
    }

    /**
     * Create {@see Set} of {@see J2eeModule.Type} objects from array
     * of those objects.
     * <p>
     * @param moduleTypes Array of NetBeans JavaEE module types.
     * @return Newly created set of NetBeans JavaEE module types from array.
     */
    Set<J2eeModule.Type> moduleTypesSetFromArray(
            final J2eeModule.Type[] moduleTypes) {
        final int size = moduleTypes != null ? moduleTypes.length : 0;
        final Set<J2eeModule.Type> moduleTypeSet = new HashSet<>(size);
        for (int i = 0; i < size; i++) {
            moduleTypeSet.add(moduleTypes[i]);
        }
        return moduleTypeSet;
    }

    ////////////////////////////////////////////////////////////////////////////
    // Constructors                                                           //
    ////////////////////////////////////////////////////////////////////////////
    
    /**
     * Creates an instance of Payara JavaEE platform.
     * <p/>
     * @param dm {@see Hk2DeploymentManager} instance containing valid reference
     *           to Payara server instance.
     * @param platforms   NetBeans JavaSE platforms supported.
     * @param profiles    NetBeans JavaEE profiles supported.
     * @param types       NetBeans JavaEE module types supported.
     * @param displayName NetBeans JavaEE platform display name.
     * @param libraryName NetBeans JavaEE library name.
     * @param lookupKey   Payara JavaEE platform lookup key.
     */
    public Hk2JavaEEPlatformImpl(final Hk2DeploymentManager dm,
            final String[] platforms,
            final Profile[] profiles, final J2eeModule.Type[] types,
            final String displayName, final String libraryName,
            final String lookupKey) {
        this.dm = dm;
        this.platforms = platforms;
        this.profiles = profiles;
        this.types = types;
        this.displayName = displayName;
        this.libraryName = libraryName;
        this.lookupKey = lookupKey;
        this.lkp = initLocalLookup();
        this.libraryProvider = Hk2LibraryProvider.getProvider(
                dm.getCommonServerSupport().getInstance());
        addFcl();
        initLibraries();
    }

    private void addFcl() {
        if (null == fcl) {
            final String path = dm.getCommonServerSupport().getInstanceProperties().get(PayaraModule.PAYARA_FOLDER_ATTR);
            final File f = new File(path, "modules"); // NOI18N
            final FileObject fo = FileUtil.toFileObject(FileUtil.normalizeFile(f));
            if (null == fo) {
                Logger.getLogger("payara-jakartaee").log(Level.WARNING, "{0} did not exist but should", f.getAbsolutePath());
                return;
            }
            fcl = new FileChangeListener() {

                @Override
                public void fileFolderCreated(final FileEvent fe) {
                    notifyLibrariesChanged();
                }

                @Override
                public void fileDataCreated(final FileEvent fe) {
                    notifyLibrariesChanged();
                }

                @Override
                public void fileChanged(final FileEvent fe) {
                    notifyLibrariesChanged();
                }

                @Override
                public void fileDeleted(final FileEvent fe) {
                    notifyLibrariesChanged();
                }

                @Override
                public void fileRenamed(final FileRenameEvent fe) {
                    notifyLibrariesChanged();
                }

                @Override
                public void fileAttributeChanged(final FileAttributeEvent fe) {
                    // we can ignore this type of change
                }
            };
            fo.addFileChangeListener(fcl);
        }
    }

    // Persistence provider strings
    private static final String PERSISTENCE_PROV_ECLIPSELINK = "org.eclipse.persistence.jpa.PersistenceProvider"; //NOI18N

    // WEB SERVICES PROPERTIES 
    // TODO - shall be removed and usages replaced by values from j2eeserver or websvc apis after api redesign
    private static final String TOOL_WSCOMPILE = "wscompile";
    private static final String TOOL_JSR109 = "jsr109";
    private static final String TOOL_WSIMPORT = "wsimport";
    private static final String TOOL_WSGEN = "wsgen";
    private static final String TOOL_KEYSTORE = "keystore";
    private static final String TOOL_KEYSTORECLIENT = "keystoreClient";
    private static final String TOOL_TRUSTSTORE = "truststore";
    private static final String TOOL_TRUSTSTORECLIENT = "truststoreClient";
    private static final String TOOL_WSIT = "wsit";
    private static final String TOOL_JAXWSTESTER = "jaxws-tester";
    private static final String TOOL_APPCLIENTRUNTIME = "appClientRuntime";
    private static final String KEYSTORE_LOCATION = "config/keystore.jks";
    private static final String TRUSTSTORE_LOCATION = "config/cacerts.jks";

    private static final String EMBEDDED_EJB_CONTAINER_PATH = "lib/embedded/glassfish-embedded-static-shell.jar";

    /** Application client container configuration file for older version (v3). */
    private static final String SUN_ACC_XML = "sun-acc.xml";

    /** Application client container configuration file for Payara v4. */
    private static final String GF_ACC_XML = "glassfish-acc.xml";

    /**
     * 
     * @param toolName 
     * @return 
     */
    @Override
    public boolean isToolSupported(String toolName) {
        // Persistence Providers
        if(PERSISTENCE_PROV_ECLIPSELINK.equals(toolName)) {
            return true;
        }

        if("org.hibernate.ejb.HibernatePersistence".equals(toolName) || //NOI18N
                "oracle.toplink.essentials.PersistenceProvider".equals(toolName) || // NOI18N
                "kodo.persistence.PersistenceProviderImpl".equals(toolName) || // NOI18N
                "org.apache.openjpa.persistence.PersistenceProviderImpl".equals(toolName)) { //NOI18N
            return true;
        }
        
        if("defaultPersistenceProviderJavaEE5".equals(toolName)) {  //NOI18N
            return true;
        }
        if("eclipseLinkPersistenceProviderIsDefault2.0".equals(toolName)) {
            return true;
        }
        String gfRootStr = dm.getProperties().getPayaraRoot();
        if (J2eePlatform.TOOL_EMBEDDABLE_EJB.equals(toolName)) {
            File jar = new File(gfRootStr, EMBEDDED_EJB_CONTAINER_PATH);
            return jar.exists() && jar.isFile() && jar.canRead();
        }

        File wsLib = null;
        
        if (gfRootStr != null) {
            wsLib = ServerUtilities.getJarName(gfRootStr, "webservices(|-osgi).jar");
        }

        // WEB SERVICES SUPPORT
        if ((wsLib != null) && (wsLib.exists())) {      // existence of webservice libraries
            if (TOOL_WSGEN.equals(toolName)) {         //NOI18N
                return true;
            }
            if (TOOL_WSIMPORT.equals(toolName)) {      //NOI18N
                return true;
            }
            if (TOOL_WSIT.equals(toolName)) {          //NOI18N
                return true;
            }
            if (TOOL_JAXWSTESTER.equals(toolName)) {  //NOI18N
                return true;
            }
            if (TOOL_JSR109.equals(toolName)) {        //NOI18N
                return true;
            }
            if (TOOL_KEYSTORE.equals(toolName)) {      //NOI18N
                return true;
            }
            if (TOOL_KEYSTORECLIENT.equals(toolName)) {//NOI18N
                return true;
            }
            if (TOOL_TRUSTSTORE.equals(toolName)) {    //NOI18N
                return true;
            }
            if (TOOL_TRUSTSTORECLIENT.equals(toolName)) {  //NOI18N
                return true;
            }
            if (TOOL_WSCOMPILE.equals(toolName)) {  //NOI18N
                return true;
            }
            if (TOOL_APPCLIENTRUNTIME.equals(toolName)) { //NOI18N
                return true;
            }
        }
        
        return false;     
    }
    
    /**
     * 
     * @param toolName 
     * @return 
     */
    @Override
    public File[] getToolClasspathEntries(String toolName) {
        String gfRootStr = dm.getProperties().getPayaraRoot();
        if (null != gfRootStr) {
            if (J2eePlatform.TOOL_EMBEDDABLE_EJB.equals(toolName)) {
                return new File[]{new File(gfRootStr, EMBEDDED_EJB_CONTAINER_PATH)};
            }
            if (TOOL_WSGEN.equals(toolName) || TOOL_WSIMPORT.equals(toolName)) {
                String[] entries = new String[]{"webservices(|-osgi).jar", //NOI18N
                    "webservices-api(|-osgi).jar", //NOI18N
                    "jaxb(|-osgi).jar", //NOI18N
                    "jaxb-api(|-osgi).jar", //NOI18N
                    "javax.activation.jar"}; //NOI18N
                List<File> cPath = new ArrayList<>();

                for (String entry : entries) {
                    File f = ServerUtilities.getWsJarName(gfRootStr, entry);
                    if ((f != null) && (f.exists())) {
                        cPath.add(f);
                    }
                }
                return cPath.toArray(new File[cPath.size()]);
            }

            if (TOOL_WSCOMPILE.equals(toolName)) {
                String[] entries = new String[] {"webservices(|-osgi).jar"}; //NOI18N
                List<File> cPath = new ArrayList<>();

                for (String entry : entries) {
                    File f = ServerUtilities.getWsJarName(gfRootStr, entry);
                    if ((f != null) && (f.exists())) {
                        cPath.add(f);
                    }
                }
                return cPath.toArray(new File[cPath.size()]);
            }

            File domainDir;
            File gfRoot = new File(gfRootStr);
            if (gfRoot.exists()) {
                String domainDirName = dm.getProperties().getDomainDir();
                if (domainDirName != null) {
                    domainDir = new File(domainDirName);

                    if (TOOL_KEYSTORE.equals(toolName) || TOOL_KEYSTORECLIENT.equals(toolName)) {
                        return new File[]{
                                    new File(domainDir, KEYSTORE_LOCATION) //NOI18N
                                };
                    }

                    if (TOOL_TRUSTSTORE.equals(toolName) || TOOL_TRUSTSTORECLIENT.equals(toolName)) {
                        return new File[]{
                                    new File(domainDir, TRUSTSTORE_LOCATION) //NOI18N
                                };
                    }
                }
            }
        } else {
            Logger.getLogger("payara-jakartaee").log(Level.INFO, "dm has no root???", new Exception());
        }
        
        return new File[0];
    }

    /**
     * Get supported JavaEE profiles.
     * <p/>
     * @return Supported JavaEE profiles.
     */
    @Override
    public Set<Profile> getSupportedProfiles() {
        return profilesSetFromArray(profiles);
    }
    
    /**
     * Get supported JavaEE profiles.
     * <p/>
     * @return Supported JavaEE profiles.
     */
    @Override
    public Set<Profile> getSupportedProfiles(final J2eeModule.Type type) {
        return profilesSetFromArray(profiles);
    }

    /**
     * Get supported JavaEE module types.
     * <p/>
     * @return Supported JavaEE module types.
     */
    @Override
    public Set<Type> getSupportedTypes() {
        return moduleTypesSetFromArray(types);
    }

    
    /**
     * 
     * @return 
     */
    @Override
    public java.io.File[] getPlatformRoots() {
        File server = getServerHome();
        if (server != null) {
            return new File[] {server};
        }
        return new File[]{};
    }

    @Override
    public File getServerHome() {
        return getExistingFolder(dm.getProperties().getPayaraRoot());
    }

    @Override
    public File getDomainHome() {
        return getExistingFolder(dm.getProperties().getDomainDir());
    }

    @Override
    public File getMiddlewareHome() {
        return getExistingFolder(dm.getProperties().getInstallRoot());
    }
    
    /**
     * 
     * @return 
     */
    @Override
    public LibraryImplementation[] getLibraries() {
        addFcl();
        return libraries.clone();
    }
    
    /**
     * 
     * @return 
     */
    @Override
    public java.awt.Image getIcon() {
        return ImageUtilities.loadImage("org/netbeans/modules/j2ee/hk2/resources/server.gif"); // NOI18N
    }
    
    /**
     * Get Payara JavaEE platform display name.
     * <p/>
     * @return Payara JavaEE platform display name.
     */
    @Override
    public String getDisplayName() {
        return displayName;
    }
    
    /**
     * Get supported JavaSE platforms.
     * <p/>
     * @return Supported JavaSE platforms.
     */
    @Override
    public Set getSupportedJavaPlatformVersions() {
        return platformsSetFromArray(platforms);
    }
    
    /**
     * Get default Payara JavaSE platform.
     * <p/>
     * Returns <code>null</code>.
     * <p/>
     * @return Default Payara JavaSE platform.
     */
    @Override
    public JavaPlatform getJavaPlatform() {
        return null;
    }
    
    /**
     * 
     */
    public void notifyLibrariesChanged() {
        initLibraries();
    }

    private static final RequestProcessor libInitThread =
            new RequestProcessor("init libs -- Hk2JavaEEPlatformImpl");
    
     private void initLibraries() {
        libInitThread.post(new Runnable() {

            @Override
            public void run() {
                libraryProvider.setJavaEELibraryImplementation(
                        lib, libraryName);
                firePropertyChange(PROP_LIBRARIES, null, libraries.clone());
            }
        });
    }

    /**
     * Return Java EE platform lookup instance.
     * <p/>
     * @return Java EE platform lookup instance.
     */
    @Override
    public Lookup getLookup() {
        return lkp;
    }

    private File getExistingFolder(String path) {
        if (path != null) {
            File returnedElement = new File(path);
            if (returnedElement.exists()) {
                return returnedElement;
            }
        }
        return null;
    }

    /* return the string within quotes
     **/
    private String quotedString(String s){
        return "\""+s+"\"";
    }

    /**
     * Get Payara version.
     * Returns {@see PayaraVersion} for current Payara server instance.
     * <p/>
     * @return Payara version.
     */
    private PayaraVersion getPFVersion() {
        PayaraVersion version = null;
        try {
            version = dm
                    .getCommonServerSupport().getInstance().getVersion();
        } catch (NullPointerException npe) {
            Logger.getLogger("payara-jakartaee").log(Level.INFO,
                    "Caught NullPointerException in Hk2JavaEEPlatformImpl "
                    + "while checking Payara version", npe);
        }
        return version;
    }

    /**
     * Get proper application client container configuration file name
     * for Payara.
     * <p/>
     * @return Application client container configuration file name
     *         for Payara.
     */
    private String getAccConfigFile() {
        final PayaraVersion version = getPFVersion();
        final String accConfigFile;
        if (version != null
                && version.ordinal() >= PayaraVersion.PF_4_1_144.ordinal()) {
            accConfigFile = GF_ACC_XML;
        } else {
            accConfigFile = SUN_ACC_XML;
        }
        StringBuilder sb = new StringBuilder(
                ServerUtils.PF_DOMAIN_CONFIG_DIR_NAME.length()
                + 1 + accConfigFile.length());
        sb.append(ServerUtils.PF_DOMAIN_CONFIG_DIR_NAME);
        sb.append(File.separatorChar);
        sb.append(accConfigFile);
        return sb.toString();
    }
    
    @Override
    public String getToolProperty(String toolName, String propertyName) {
        if (J2eePlatform.TOOL_APP_CLIENT_RUNTIME.equals(toolName)) {
            File root = new File(dm.getProperties().getPayaraRoot());
            String domainPath = dm.getProperties().getDomainDir();
            if (J2eePlatform.TOOL_PROP_MAIN_CLASS.equals(propertyName)) {
                return "org.glassfish.appclient.client.AppClientFacade"; // NOI18N
            }
            if (J2eePlatform.TOOL_PROP_MAIN_CLASS_ARGS.equals(propertyName)) {
                return "${j2ee.appclient.tool.args}"; // NOI18N
            }
            if (J2eePlatform.TOOL_PROP_JVM_OPTS.equals(propertyName)) {
                if(domainPath != null) {
                    StringBuilder sb = new StringBuilder();
                    sb.append("-Djava.endorsed.dirs=");
                     sb.append(quotedString(new File(root,"lib/endorsed").getAbsolutePath()));
                    sb.append(File.pathSeparator);
                     sb.append(quotedString(new File(root,"modules/endorsed").getAbsolutePath()));
                     sb.append(" -javaagent:");
                     String url = dm.getCommonServerSupport().getInstanceProperties().get(PayaraModule.URL_ATTR);
                     File f = new File(root,"lib/gf-client.jar"); // NOI18N
                     if (f.exists()) {
                        sb.append(quotedString(f.getAbsolutePath()));
                     } else {
                        sb.append(quotedString(new File(root,"modules/gf-client.jar").getAbsolutePath()));
                    }
                      sb.append("=mode=acscript,arg=-configxml,arg=");
                      sb.append(quotedString(new File(domainPath, getAccConfigFile()).getAbsolutePath()));
                      sb.append(",client=jar=");
//                  sb.append(""); // path to /tmp/test/ApplicationClient1Client.jar
//                   sb.append(" -jar ");
//                    sb.append(""); // path to /tmp/test/ApplicationClient1Client.jar
                    return sb.toString();
                } else {
                    return null;
                }
            }
            if (J2eePlatform.TOOL_PROP_CLIENT_JAR_LOCATION.equals(propertyName)) {
                if(domainPath != null) {
                    FileObject location = FileUtil.toFileObject(FileUtil.normalizeFile(new File(domainPath)));
                    if (location == null) {
                        return null;
                    }
                    return (FileUtil.toFile(location).getAbsolutePath())+File.separator+"generated"+File.separator+"xml"; // NOI18N
                } else {
                    return null;
                }
            }
            if ("j2ee.appclient.args".equals(propertyName)) { // NOI18N
                return null; // "-configxml " + quotedString(new File(dmProps.getLocation(), dmProps.getDomainName() +
                // "/config/sun-acc.xml").getAbsolutePath()); // NOI18N
            }
        }
        return null;
    }

    /**
     * Get Payara bundled libraries provider.
     * <p/>
     * @return Payara bundled libraries provider.
     */
    public Hk2LibraryProvider getLibraryProvider() {
        return libraryProvider;
    }

    private class JaxRsStackSupportImpl implements JaxRsStackSupportImplementation {
        
        // Bug# 233840 - Fixing to avoid AssertionError and provide library
        // for GF4. But JAR names remain hardcoded. This shall be rewritten
        // to use Hk2LibraryProvider!
        /* (non-Javadoc)
         * @see org.netbeans.modules.javaee.specs.support.spi.JaxRsStackSupportImplementation#addJsr311Api(org.netbeans.api.project.Project)
         */
        @Override
        public boolean addJsr311Api(final Project project) {
            final Library library = libraryProvider.getJaxRsLibrary();
            final FileObject sourceRoot = getSourceRoot(project);
            if (library != null && sourceRoot != null) {
                try {
                    String classPathType = hasJee6Profile()
                            ? JavaClassPathConstants.COMPILE_ONLY
                            : ClassPath.COMPILE;
                    return ProjectClassPathModifier.addLibraries(
                            new Library[] {library}, sourceRoot, classPathType);
                } catch (UnsupportedOperationException | IOException ex) {
                    return false;
                }
            }
            // TODO: Rewrite to use Hk2LibraryProvider#getJaxRsName()
            // or getJaxRsClassPathURLs()
            final PayaraVersion version = getPFVersion();
            try {
                if (version == null) {
                    return false;
                }
                else if (version.equalsMajorMinor(PayaraVersion.PF_4_1_144)) {
                    final File javaxWsRs = ServerUtilities.getJarName(dm.getProperties().
                            getPayaraRoot(), "javax.ws.rs-api.jar"); // NOI18N
                    if ( javaxWsRs== null || !javaxWsRs.exists()){
                        return false;
                    }
                    return addJars(project, Collections.singletonList(
                            Utilities.toURI(javaxWsRs).toURL()));
                }
            } catch (MalformedURLException ex) {
                return false;
            }
            return false;
        }

        /* (non-Javadoc)
         * @see org.netbeans.modules.javaee.specs.support.spi.JaxRsStackSupportImplementation#extendsJerseyProjectClasspath(org.netbeans.api.project.Project)
         */
        @Override
        public boolean extendsJerseyProjectClasspath( Project project ) {
            Library library = libraryProvider.getJerseyLibrary();
            FileObject sourceRoot = getSourceRoot(project);
            if (sourceRoot == null) {
                return false;
            }
            try {
                String classPathType;
                if (hasJee6Profile()) {
                    classPathType = JavaClassPathConstants.COMPILE_ONLY;
                }
                else {
                    classPathType = ClassPath.COMPILE;
                }
                return ProjectClassPathModifier.addLibraries(
                        new Library[] { library }, sourceRoot, classPathType);
            }
            catch (UnsupportedOperationException | IOException ex) {
                return false;
            }
            /*List<URL> urls = getJerseyLibraryURLs();
            if ( urls.sdkSize() >0 ){
                return addJars( project , urls );
            }*/
        }
        
        @Override
        public void removeJaxRsLibraries(final Project project) {
            final Library library = libraryProvider.getJerseyLibrary();
            final FileObject sourceRoot = getSourceRoot(project);
            if ( sourceRoot != null){
                final String[] classPathTypes = new String[]{ ClassPath.COMPILE , 
                        JavaClassPathConstants.COMPILE_ONLY };
                for (String type : classPathTypes) {
                    try {
                        ProjectClassPathModifier.removeLibraries( new Library[]{
                                library} ,sourceRoot, type);
                    }    
                    catch (UnsupportedOperationException | IOException ex) {
                        Logger.getLogger(JaxRsStackSupportImpl.class.getName()).
                                log (Level.INFO, null , ex );
                    }
                }     
            }
            /*List<URL> urls = getJerseyLibraryURLs();
            if ( urls.sdkSize() >0 ){
                SourceGroup[] sourceGroups = ProjectUtils.getSources(project).getSourceGroups(
                    JavaProjectConstants.SOURCES_TYPE_JAVA);
                if (sourceGroups == null || sourceGroups.length < 1) {
                    return;
                }
                FileObject sourceRoot = sourceGroups[0].getRootFolder();
                String[] classPathTypes = new String[]{ ClassPath.COMPILE , ClassPath.EXECUTE };
                for (String type : classPathTypes) {
                    try {
                        ProjectClassPathModifier.removeRoots(urls.toArray( 
                            new URL[ urls.sdkSize()]), sourceRoot, type);
                    }    
                    catch(UnsupportedOperationException ex) {
                        Logger.getLogger( JaxRsStackSupportImpl.class.getName() ).
                                log (Level.INFO, null , ex );
                    }
                    catch( IOException e ){
                        Logger.getLogger( JaxRsStackSupportImpl.class.getName() ).
                                log(Level.INFO, null , e );
                    }
                }     
            }*/
        }
        
        @Override
        public void configureCustomJersey( Project project ){
        }
        
        /* (non-Javadoc)
         * @see org.netbeans.modules.javaee.specs.support.spi.JaxRsStackSupportImplementation#isBundled(java.lang.String)
         */
        @Override
        public boolean isBundled(final String classFqn ) {
            final List<URL> urls = libraryProvider.getJerseyClassPathURLs();
            for( URL url : urls ){
                FileObject root = URLMapper.findFileObject(url);
                if ( FileUtil.isArchiveFile(root)){
                    root = FileUtil.getArchiveRoot(root);
                }
                final String path = classFqn.replace('.', '/')+".class";
                if ( root.getFileObject(path )!= null ){
                    return true;
                }
            }
            return false;
        }

        private FileObject getSourceRoot(final Project project) {
            final SourceGroup[] sourceGroups = ProjectUtils.getSources(project)
                    .getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
            if (sourceGroups == null || sourceGroups.length < 1) {
                return null;
            }
            return sourceGroups[0].getRootFolder();
        }
        
        private boolean hasJee6Profile(){
            final Set<Profile> profiles = getSupportedProfiles();
            return profiles.contains(Profile.JAVA_EE_6_FULL) || 
                profiles.contains(Profile.JAVA_EE_6_WEB) ;
        }
        
        private void addURL(final Collection<URL> urls, final File file ){
            if ( file == null || !file.exists()) {
                return;
            }
            try {
                urls.add(Utilities.toURI(file).toURL());
            } catch (MalformedURLException ex) {
                // ignore the file
            }
        }
        
        private boolean addJars(final Project project, Collection<URL> jars ){
            final List<URL> urls = new ArrayList<>();
            for (URL url : jars) {
                if ( FileUtil.isArchiveFile( url)){
                    urls.add(FileUtil.getArchiveRoot(url));
                }
            }
            final SourceGroup[] sourceGroups = ProjectUtils.getSources(project).getSourceGroups(
                JavaProjectConstants.SOURCES_TYPE_JAVA);
            if (sourceGroups == null || sourceGroups.length < 1) {
               return false;
            }
            final FileObject sourceRoot = sourceGroups[0].getRootFolder();
            try {
                final String classPathType;
                if ( hasJee6Profile() ){
                    classPathType = JavaClassPathConstants.COMPILE_ONLY;
                }
                else {
                    classPathType = ClassPath.COMPILE;
                }
                ProjectClassPathModifier.addRoots(urls.toArray( new URL[ urls.size()]), 
                        sourceRoot, classPathType );
            } 
            catch (UnsupportedOperationException | IOException ex) {
                return false;
            }
            return true;
        }
        
        /**
         * Get Payara version from instance stored in deployment manager.
         * <p/>
         * @return Payara version from instance stored in deployment manager.
         */
        private PayaraVersion getPFVersion() {
            PayaraVersion version = null;
            try {
                version = dm
                        .getCommonServerSupport().getInstance().getVersion();
            } catch (NullPointerException npe) {
                Logger.getLogger("payara-jakartaee").log(Level.INFO,
                        "Caught NullPointerException in Hk2JavaEEPlatformImpl "
                        + "while checking Payara version", npe);
            }
            return version;
        }
    }
}
