/*
 * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package override;

import java.io.*;
import java.net.*;
import java.util.Set;
import com.sun.enterprise.deployment.archivist.*;
import com.sun.enterprise.deployment.*;
import org.glassfish.deployment.common.Descriptor;

import org.glassfish.api.deployment.archive.ReadableArchive;
import com.sun.enterprise.deploy.shared.ArchiveFactory;
import com.sun.enterprise.module.ModulesRegistry;
import com.sun.enterprise.module.single.StaticModulesRegistry;
import com.sun.enterprise.module.bootstrap.StartupContext;
import org.glassfish.api.admin.ProcessEnvironment;
import org.glassfish.api.admin.ProcessEnvironment.ProcessType;
import org.glassfish.internal.api.Globals;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.utilities.ServiceLocatorUtilities;

public class OverrideTest {

    private static ServiceLocator serviceLocator = null;

    private static final String EXPECTED_RESOURCE_JNDI_NAME = "jdbc/__default";
    private static final String EXPECTED_RESOURCE_DESCRIPTION = "override";
    private static final String EXPECTED_RESOURCE_SHARING_SCOPE = "Unshareable";
    private static final String EXPECTED_RESOURCE_AUTHORIZATION = "Container";

    public static void main(String args[]) {

        String fileName = args[0];
        String ext = getExtension(fileName);
        String archiveType = ext.substring(1);
        if ("jar".equals(archiveType)) {
          if (fileName.contains("car")) {
            archiveType = "car";
          } else {
            archiveType = "ejb";
          }
        }

        boolean expectException = false;
        if (args.length > 1) {
          if ("true".equals(args[1])) {
            expectException = true;
          }
        }

        String outputFileName = fileName + "1" + ext;
        String outputFileName2 = fileName + "2" + ext;

        prepareServiceLocator();

        ArchivistFactory archivistFactory = serviceLocator.getService(ArchivistFactory.class);
        ArchiveFactory archiveFactory = serviceLocator.getService(ArchiveFactory.class);
        Archivist archivist = null;

        ReadableArchive archive = null;
        
        // first read/parse and write out the original valid archive
        try {
            File archiveFile = new File(fileName);
            archive = archiveFactory.openArchive(
                archiveFile);
            ClassLoader classloader = new URLClassLoader(
                new URL[] { new File(archiveFile, "WEB-INF/classes").toURL() });

            archivist = archivistFactory.getArchivist(archiveType, classloader);
            archivist.setAnnotationProcessingRequested(true);
            JndiNameEnvironment nameEnv = (JndiNameEnvironment)archivist.open(archiveFile);

            Set<ResourceReferenceDescriptor> resRefDescs = nameEnv.getResourceReferenceDescriptors(); 
 
            for (ResourceReferenceDescriptor resRef : resRefDescs) {
                String refName = resRef.getName();
                String jndiName = resRef.getJndiName();
                String mappedName = resRef.getMappedName();
                String lookupName = resRef.getLookupName();
                String description = resRef.getDescription();
                String auth = resRef.getAuthorization();
                String scope = resRef.getSharingScope();
                log ("Resource ref [" + refName + "] with JNDI name: " + jndiName + ", description: " + description + ", authorization: " + auth + ", sharing scope: " + scope + ", mappedName: " + mappedName + ", lookupName: " + lookupName);
                if (refName.equals("myDS7") && 
                    !description.equals(EXPECTED_RESOURCE_DESCRIPTION)) {
                    log("Descriptor did not override the @Resource description attribute as expected");
                    fail();
                } else if (refName.equals("myDS5and6")) { 
                    Set<InjectionTarget> targets = resRef.getInjectionTargets();
                    for (InjectionTarget target : targets) {
                       log("Target class name: " + target.getClassName());
                       log("Target name: " + target.getTargetName());
                    }
                    if (targets.size() != 2) {
                        log("The additional injection target specified in the descriptor is not used as expected");
                        fail();
                    }
                } else if (refName.equals("myDS8") && 
                    !mappedName.equals(EXPECTED_RESOURCE_JNDI_NAME)) {
                    log("Descriptor did not override the @Resource mapped-name attribute as expected");
                    fail();
                } else if (refName.equals("myDS7") && 
                    !scope.equals(EXPECTED_RESOURCE_SHARING_SCOPE)) {
                    log("Descriptor did not override the @Resource sharing scope attribute as expected");
                    fail();
                } else if (refName.equals("myDS7") && 
                    !auth.equals(EXPECTED_RESOURCE_AUTHORIZATION)) {
                    log("Descriptor did not override the @Resource authorization attribute as expected");
                    fail();
                } else if (refName.equals("myDS7") && 
                    !lookupName.equals(EXPECTED_RESOURCE_JNDI_NAME)) {
                    log("Descriptor did not override the @Resource lookup name attribute as expected");
                    fail();
                }
            }
  
        } catch (Exception e) {
            e.printStackTrace();
            log("Input archive: [" + fileName + 
                "] is not valid");
            fail();
        } finally {
            try {
                if (archive != null) {
                    archive.close();
                }
            } catch(IOException ioe) {
            }
        }
    }

    private static void log(String message) {
        System.out.println("[dol.override.OverrideTest]:: " + message);
        System.out.flush();
    }

    private static void pass() {
        log("PASSED: devtests/deployment/dol/override");
        System.exit(0);
    }

    private static void fail() {
        log("FAILED: devtests/deployment/dol/override");
        System.exit(-1);
    }

    private static String getExtension(String file) {
        String ext = file.substring(file.lastIndexOf("."));
        return ext;
    }

    private static void prepareServiceLocator() {
        if ( (serviceLocator == null) ) {
            // Bootstrap a hk2 environment.
            ModulesRegistry registry = new StaticModulesRegistry(Thread.currentThread().getContextClassLoader());
            serviceLocator = registry.createServiceLocator("default");
            StartupContext startupContext = new StartupContext();

            ServiceLocatorUtilities.addOneConstant(serviceLocator, startupContext);
            ServiceLocatorUtilities.addOneConstant(serviceLocator, 
                new ProcessEnvironment(ProcessEnvironment.ProcessType.Other));

            Globals.setDefaultHabitat(serviceLocator);
        }
    }

}
