/*
 * 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.apache.openejb.config;

import org.apache.openejb.OpenEJBException;
import org.apache.openejb.jee.Connector;
import org.apache.openejb.jee.EjbJar;
import org.apache.openejb.jee.JAXBContextFactory;
import org.apache.openejb.jee.jpa.EntityMappings;
import org.apache.openejb.jee.jpa.JpaJaxbUtil;
import org.apache.openejb.jee.jpa.unit.Persistence;
import org.apache.openejb.jee.jpa.unit.PersistenceUnit;
import org.apache.openejb.jee.oejb2.GeronimoEjbJarType;
import org.apache.openejb.jee.oejb2.JaxbOpenejbJar2;
import org.apache.openejb.jee.oejb3.JaxbOpenejbJar3;
import org.apache.openejb.jee.oejb3.OpenejbJar;
import org.apache.openejb.loader.IO;
import org.apache.openejb.loader.Options;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.sxc.EjbJarXml;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

public class OutputGeneratedDescriptors implements DynamicDeployer {
    private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB_STARTUP_CONFIG, "org.apache.openejb.util.resources");
    public static final String OUTPUT_DESCRIPTORS = "openejb.descriptors.output";
    public static final String OUTPUT_DESCRIPTORS_FOLDER = "openejb.descriptors.output.folder";

    public AppModule deploy(final AppModule appModule) throws OpenEJBException {
        boolean output = SystemInstance.get().getOptions().get(OUTPUT_DESCRIPTORS, false);

        if (output && appModule.getCmpMappings() != null) {

            writeGenratedCmpMappings(appModule);
        }

        for (final EjbModule ejbModule : appModule.getEjbModules()) {
            final Options options = new Options(ejbModule.getOpenejbJar().getProperties(), SystemInstance.get().getOptions());

            final ValidationContext context = ejbModule.getValidation();

            // output descriptors by default if there are validation errors
            final boolean invalid = context.hasErrors() || context.hasFailures();

            output = options.get(OUTPUT_DESCRIPTORS, invalid);

            if (output) {
                if (ejbModule.getEjbJar() != null) {
                    writeEjbJar(ejbModule);
                }

                if (ejbModule.getOpenejbJar() != null) {
                    writeOpenejbJar(ejbModule);
                }

                writeGeronimoOpenejb(ejbModule);
            }
        }

        for (final ConnectorModule connectorModule : appModule.getConnectorModules()) {
            writeRaXml(connectorModule);
        }

        return appModule;
    }

    private void writeRaXml(final ConnectorModule connectorModule) {
        try {
            final Connector connector = connectorModule.getConnector();

            final File tempFile = tempFile("ra-", connectorModule.getModuleId() + ".xml");

            final OutputStream out = IO.write(tempFile);
            try {
                final JAXBContext ctx = JAXBContextFactory.newInstance(Connector.class);
                final Marshaller marshaller = ctx.createMarshaller();
                marshaller.marshal(connector, out);
                logger.info("Dumping Generated ra.xml to: " + tempFile.getAbsolutePath());
            } catch (final JAXBException e) {
                // no-op
            } finally {
                IO.close(out);
            }
        } catch (final IOException e) {
            // no-op
        }
    }

    private File tempFile(final String start, final String end) throws IOException {
        if (SystemInstance.get().getOptions().get(OUTPUT_DESCRIPTORS_FOLDER, (String) null) != null) {
            final File tmp = new File(SystemInstance.get().getOptions().get(OUTPUT_DESCRIPTORS_FOLDER, ""));
            if (!tmp.exists()) {
                if (!tmp.mkdirs()) {
                    throw new IOException("can't create " + tmp.getAbsolutePath());
                }
            }
            return new File(tmp, start + Long.toString(new Random().nextInt()) + end);
        } else {
            try {
                return File.createTempFile(start, end);
            } catch (final Throwable e) {

                final File tmp = new File("tmp");
                if (!tmp.exists() && !tmp.mkdirs()) {
                    throw new IOException("Failed to create local tmp directory: " + tmp.getAbsolutePath());
                }

                return File.createTempFile(start, end, tmp);
            }
        }
    }

    private void writeGenratedCmpMappings(final AppModule appModule) {

        for (final PersistenceModule persistenceModule : appModule.getPersistenceModules()) {
            try {
                final Persistence persistence = persistenceModule.getPersistence();
                if (hasCmpPersistenceUnit(persistence)) {
                    final File tempFile = tempFile("persistence-", ".xml");
                    final OutputStream out = IO.write(tempFile);
                    try {
                        JpaJaxbUtil.marshal(Persistence.class, persistence, out);
                        logger.info("Dumping Generated CMP persistence.xml to: " + tempFile.getAbsolutePath());
                    } catch (final JAXBException e) {
                        // no-op
                    } finally {
                        IO.close(out);
                    }
                }
            } catch (final IOException e) {
                // no-op
            }
        }
        try {
            final File tempFile = tempFile("openejb-cmp-generated-orm-", ".xml");
            final OutputStream out = IO.write(tempFile);
            try {
                JpaJaxbUtil.marshal(EntityMappings.class, appModule.getCmpMappings(), out);
                logger.info("Dumping Generated CMP mappings.xml to: " + tempFile.getAbsolutePath());
            } catch (final JAXBException e) {
                // no-op
            } finally {
                IO.close(out);
            }
        } catch (final IOException e) {
            // no-op
        }
    }

    private boolean hasCmpPersistenceUnit(final Persistence persistence) {
        for (final PersistenceUnit unit : persistence.getPersistenceUnit()) {
            if (unit.getName().startsWith("cmp")) {
                return true;
            }
        }
        return false;
    }

    private void writeOpenejbJar(final EjbModule ejbModule) {
        try {
            final OpenejbJar openejbJar = ejbModule.getOpenejbJar();
            final File tempFile = tempFile("openejb-jar-", ejbModule.getModuleId() + ".xml");

            final OutputStream out = IO.write(tempFile);
            try {
                JaxbOpenejbJar3.marshal(OpenejbJar.class, openejbJar, out);
                logger.info("Dumping Generated openejb-jar.xml to: " + tempFile.getAbsolutePath());
            } catch (final JAXBException e) {
                // no-op
            } finally {
                IO.close(out);
            }
        } catch (final Exception e) {
            // no-op
        }
    }

    private void writeGeronimoOpenejb(final EjbModule ejbModule) {
        try {
            final GeronimoEjbJarType geronimoEjbJarType = (GeronimoEjbJarType) ejbModule.getAltDDs().get("geronimo-openejb.xml");

            if (geronimoEjbJarType == null) {
                return;
            }

            final File tempFile = tempFile("geronimo-openejb-", ejbModule.getModuleId() + ".xml");

            final OutputStream out = IO.write(tempFile);
            try {
                JaxbOpenejbJar2.marshal(GeronimoEjbJarType.class, geronimoEjbJarType, out);
                logger.info("Dumping Generated geronimo-openejb.xml to: " + tempFile.getAbsolutePath());
            } catch (final JAXBException e) {
                // no-op
            } finally {
                IO.close(out);
            }
        } catch (final Exception e) {
            // no-op
        }
    }

    private void writeEjbJar(final EjbModule ejbModule) {
        try {
            final EjbJar ejbJar = ejbModule.getEjbJar();
            final File tempFile = tempFile("ejb-jar-", ejbModule.getModuleId() + ".xml");

            final OutputStream out = IO.write(tempFile);
            try {
                EjbJarXml.marshal(ejbJar, out);
                logger.info("Dumping Generated ejb-jar.xml to: " + tempFile.getAbsolutePath());
            } catch (final JAXBException e) {
                // no-op
            } finally {
                IO.close(out);
            }
        } catch (final Exception e) {
            // no-op
        }
    }
}
