/*
 * 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 javax.activation;

import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.net.URL;

public class DataHandler implements Transferable {
    private final DataSource ds;
    private final DataFlavor flavor;

    private CommandMap commandMap;
    private DataContentHandler dch;

    public DataHandler(DataSource ds) {
        this.ds = ds;
        this.flavor = new ActivationDataFlavor(ds.getContentType(), null);
    }

    public DataHandler(Object data, String type) {
        this.ds = new ObjectDataSource(data, type);
        this.flavor = new ActivationDataFlavor(data.getClass(), null);
    }

    public DataHandler(URL url) {
        this.ds = new URLDataSource(url);
        this.flavor = new ActivationDataFlavor(ds.getContentType(), null);
    }

    public DataSource getDataSource() {
        return ds;
    }

    public String getName() {
        return ds.getName();
    }

    public String getContentType() {
        return ds.getContentType();
    }

    public InputStream getInputStream() throws IOException {
        return ds.getInputStream();
    }

    public void writeTo(OutputStream os) throws IOException {
        if (ds instanceof ObjectDataSource) {
            ObjectDataSource ods = (ObjectDataSource) ds;
            DataContentHandler dch = getDataContentHandler();
            if (dch == null) {
                throw new UnsupportedDataTypeException(ods.mimeType);
            }
            dch.writeTo(ods.data, ods.mimeType, os);
        } else {
            byte[] buffer = new byte[1024];
            InputStream is = getInputStream();
            try {
                int count;
                while ((count = is.read(buffer)) != -1) {
                    os.write(buffer, 0, count);
                }
            } finally {
                is.close();
            }
        }
    }

    public OutputStream getOutputStream() throws IOException {
        return ds.getOutputStream();
    }

    public synchronized DataFlavor[] getTransferDataFlavors() {
        return getDataContentHandler().getTransferDataFlavors();
    }

    public boolean isDataFlavorSupported(DataFlavor flavor) {
        DataFlavor[] flavors = getTransferDataFlavors();
        for (int i = 0; i < flavors.length; i++) {
            DataFlavor dataFlavor = flavors[i];
            if (dataFlavor.equals(flavor)) {
                return true;
            }
        }
        return false;
    }

    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
        DataContentHandler dch = getDataContentHandler();
        if (dch != null) {
            return dch.getTransferData(flavor, ds);
        } else if (this.flavor.match(flavor)) {
            if (ds instanceof ObjectDataSource) {
                return ((ObjectDataSource) ds).data;
            } else {
                return ds.getInputStream();
            }
        } else {
            throw new UnsupportedFlavorException(flavor);
        }
    }

    public CommandInfo[] getPreferredCommands() {
        return getCommandMap().getPreferredCommands(ds.getContentType());
    }

    public CommandInfo[] getAllCommands() {
        return getCommandMap().getAllCommands(ds.getContentType());
    }

    public CommandInfo getCommand(String cmdName) {
        return getCommandMap().getCommand(ds.getContentType(), cmdName);
    }

    public Object getContent() throws IOException {
        if (ds instanceof ObjectDataSource) {
            return ((ObjectDataSource) ds).data;
        } else {
            DataContentHandler dch = getDataContentHandler();
            if (dch != null) {
                return dch.getContent(ds);
            } else {
                return ds.getInputStream();
            }
        }
    }

    public Object getBean(CommandInfo cmdinfo) {
        try {
            return cmdinfo.getCommandObject(this, this.getClass().getClassLoader());
        } catch (IOException e) {
            return null;
        } catch (ClassNotFoundException e) {
            return null;
        }
    }

    /**
     * A local implementation of DataSouce used to wrap an Object and mime-type.
     */
    private class ObjectDataSource implements DataSource {
        private final Object data;
        private final String mimeType;

        public ObjectDataSource(Object data, String mimeType) {
            this.data = data;
            this.mimeType = mimeType;
        }

        public String getName() {
            return null;
        }

        public String getContentType() {
            return mimeType;
        }

        public InputStream getInputStream() throws IOException {
            final DataContentHandler dch = getDataContentHandler();
            if (dch == null) {
                throw new UnsupportedDataTypeException(mimeType);
            }
            final PipedInputStream is = new PipedInputStream();
            final PipedOutputStream os = new PipedOutputStream(is);
            Thread thread = new Thread("DataHandler Pipe Pump") {
                public void run() {
                    try {
                        try {
                            dch.writeTo(data, mimeType, os);
                        } finally {
                            os.close();
                        }
                    } catch (IOException e) {
                        // ignore, per spec - doh!
                    }
                }
            };
            thread.start();
            return is;
        }

        public OutputStream getOutputStream() throws IOException {
            return null;
        }
    }

    public synchronized void setCommandMap(CommandMap commandMap) {
        this.commandMap = commandMap;
        this.dch = null;
    }

    private synchronized CommandMap getCommandMap() {
        return commandMap != null ? commandMap : CommandMap.getDefaultCommandMap();
    }

    /**
     * Search for a DataContentHandler for our mime type.
     * The search is performed by first checking if a global factory has been set using
     * {@link #setDataContentHandlerFactory(DataContentHandlerFactory)};
     * if found then it is called to attempt to create a handler.
     * If this attempt fails, we then call the command map set using {@link #setCommandMap(CommandMap)}
     * (or if that has not been set, the default map returned by {@link CommandMap#getDefaultCommandMap()})
     * to create the handler.
     *
     * The resulting handler is cached until the global factory is changed.
     *
     * @return
     */
    private synchronized DataContentHandler getDataContentHandler() {
        DataContentHandlerFactory localFactory;
        synchronized (DataHandler.class) {
            if (factory != originalFactory) {
                // setDCHF was called - clear our cached copy of the DCH and DCHF
                dch = null;
                originalFactory = factory;
            }
            localFactory = originalFactory;
        }
        if (dch == null) {
            // get the main mime-type portion of the content.
            String mimeType = getMimeType(ds.getContentType());
            if (localFactory != null) {
                dch = localFactory.createDataContentHandler(mimeType);
            }
            if (dch == null) {
                dch = getCommandMap().createDataContentHandler(mimeType);
            }
        }
        return dch;
    }

    /**
     * Retrieve the base MIME type from a content type.  This parses
     * the type into its base components, stripping off any parameter
     * information.
     *
     * @param contentType
     *               The content type string.
     *
     * @return The MIME type identifier portion of the content type.
     */
    private String getMimeType(String contentType) {
        try {
            MimeType mimeType = new MimeType(contentType);
            return mimeType.getBaseType();
        } catch (MimeTypeParseException e) {
        }
        return contentType;
    }

    /**
     * This is used to check if the DataContentHandlerFactory has been changed.
     * This is not specified behaviour but this check is required to make this work like the RI.
     */
    private DataContentHandlerFactory originalFactory;

    {
        synchronized (DataHandler.class) {
            originalFactory = factory;
        }
    }

    private static DataContentHandlerFactory factory;

    /**
     * Set the DataContentHandlerFactory to use.
     * If this method has already been called then an Error is raised.
     *
     * @param newFactory the new factory
     * @throws SecurityException if the caller does not have "SetFactory" RuntimePermission
     */
    public static synchronized void setDataContentHandlerFactory(DataContentHandlerFactory newFactory) {
        if (factory != null) {
            throw new Error("javax.activation.DataHandler.setDataContentHandlerFactory has already been defined");
        }
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkSetFactory();
        }
        factory = newFactory;
    }
}
