/**
 *
 * Magnolia SimpleMedia Module (http://www.openmindlab.com/lab/products/media.html)
 * Copyright (C)2008 - 2010, Openmind S.r.l. http://www.openmindonline.it
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package net.sourceforge.openutils.mgnlmedia.media.pages;

import info.magnolia.cms.beans.runtime.Document;
import info.magnolia.cms.core.Content;
import info.magnolia.cms.core.HierarchyManager;
import info.magnolia.cms.i18n.Messages;
import info.magnolia.cms.security.AccessDeniedException;
import info.magnolia.context.MgnlContext;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.jcr.RepositoryException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sourceforge.openutils.mgnlmedia.media.lifecycle.MediaModule;
import net.sourceforge.openutils.mgnlmedia.media.tags.el.MediaEl;
import net.sourceforge.openutils.mgnlmedia.media.utils.MediaLoadUtils;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Page that contains the tree and the foldere view.
 * @author molaschi
 * @version $Id: MediaBrowserPage.java 2333 2010-05-02 18:08:24Z fgiust $
 */
public class MediaBrowserPage extends MessagesTemplatedMVCHandler
{

    /**
     * Logger.
     */
    private Logger log = LoggerFactory.getLogger(MediaBrowserPage.class);

    private String cacheKiller;

    private String actMedia;

    private boolean selectMedia;

    private String nodeid;

    private String openPath;

    private String actMediaHandle;

    private String mediaType;

    private String parentPath;

    private Document zipFile;

    /**
     * @param name command name
     * @param request
     * @param response
     */
    public MediaBrowserPage(String name, HttpServletRequest request, HttpServletResponse response)
    {
        super(name, request, response);
        cacheKiller = String.valueOf(new Date().getTime());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void init()
    {
        super.init();
        if (StringUtils.isNotBlank(actMedia))
        {
            HierarchyManager mgr = MgnlContext.getHierarchyManager(MediaModule.REPO);
            try
            {
                Content media = mgr.getContentByUUID(actMedia);
                openPath = media.getParent().getHandle();
                actMediaHandle = media.getHandle();
            }
            catch (RepositoryException ex)
            {
                log.warn("Error retrieving media {}", actMedia);
            }
        }
    }

    /**
     * Save Zip file command
     * @return view
     */
    public String saveZip()
    {
        InputStream zipStream = null;
        File temp = null;
        try
        {
            temp = File.createTempFile("zipmedia", ".zip");
            FileOutputStream fos = new FileOutputStream(temp);

            zipStream = zipFile.getStream();
            IOUtils.copy(zipStream, fos);

            IOUtils.closeQuietly(fos);
            ZipFile zip = new ZipFile(temp);
            Enumeration< ? extends ZipEntry> entries = zip.entries();
            while (entries.hasMoreElements())
            {
                ZipEntry entry = entries.nextElement();

                String path = entry.getName();

                if (!entry.isDirectory())
                {

                    InputStream inputStream = zip.getInputStream(entry);

                    String parent = StringUtils.trimToEmpty(parentPath) + "/" + path;
                    parent = StringUtils.replace(parent, "\\", "/");
                    parent = StringUtils.replace(parent, "//", "/");
                    if (!parent.startsWith("/"))
                    {
                        parent = "/" + parent;
                    }
                    String filename = StringUtils.substringAfterLast(parent, "/");
                    parent = StringUtils.substringBeforeLast(parent, "/");

                    MediaLoadUtils.loadEntry(
                        inputStream,
                        StringUtils.defaultIfEmpty(parent, "/fromzip"),
                        filename,
                        false);

                }
            }
        }
        catch (IOException e)
        {
            log.error(e.getMessage(), e);
        }
        catch (AccessDeniedException e)
        {
            log.error(e.getMessage(), e);
        }
        catch (RepositoryException e)
        {
            log.error(e.getMessage(), e);
        }
        finally
        {
            IOUtils.closeQuietly(zipStream);
        }

        FileUtils.deleteQuietly(temp);

        this.openPath = parentPath;

        return this.show();
    }

    /**
     * Returns the cacheKiller.
     * @return the cacheKiller
     */
    public String getCacheKiller()
    {
        return cacheKiller;
    }

    /**
     * Sets the cacheKiller.
     * @param cacheKiller the cacheKiller to set
     */
    public void setCacheKiller(String cacheKiller)
    {
        this.cacheKiller = cacheKiller;
    }

    /**
     * Returns the actMedia.
     * @return the actMedia
     */
    public String getActMedia()
    {
        return actMedia;
    }

    /**
     * Sets the actMedia.
     * @param actMedia the actMedia to set
     */
    public void setActMedia(String actMedia)
    {
        this.actMedia = actMedia;
    }

    /**
     * Returns the selectMedia.
     * @return the selectMedia
     */
    public boolean isSelectMedia()
    {
        return selectMedia;
    }

    /**
     * Sets the selectMedia.
     * @param selectMedia the selectMedia to set
     */
    public void setSelectMedia(boolean selectMedia)
    {
        this.selectMedia = selectMedia;
    }

    /**
     * Returns the nodeid.
     * @return the nodeid
     */
    public String getNodeid()
    {
        return nodeid;
    }

    /**
     * Sets the nodeid.
     * @param nodeid the nodeid to set
     */
    public void setNodeid(String nodeid)
    {
        this.nodeid = nodeid;
    }

    /**
     * Returns the openPath.
     * @return the openPath
     */
    public String getOpenPath()
    {
        return openPath;
    }

    /**
     * Sets the openPath.
     * @param openPath the openPath to set
     */
    public void setOpenPath(String openPath)
    {
        this.openPath = openPath;
    }

    /**
     * Returns the actMediaHandle.
     * @return the actMediaHandle
     */
    public String getActMediaHandle()
    {
        return actMediaHandle;
    }

    /**
     * Sets the actMediaHandle.
     * @param actMediaHandle the actMediaHandle to set
     */
    public void setActMediaHandle(String actMediaHandle)
    {
        this.actMediaHandle = actMediaHandle;
    }

    /**
     * Returns the mediaType.
     * @return the mediaType
     */
    public String getMediaType()
    {
        return mediaType;
    }

    /**
     * Sets the mediaType.
     * @param mediaType the mediaType to set
     */
    public void setMediaType(String mediaType)
    {
        this.mediaType = mediaType;
    }

    /**
     * Returns the parentPath.
     * @return the parentPath
     */
    public String getParentPath()
    {
        return parentPath;
    }

    /**
     * Sets the parentPath.
     * @param parentPath the parentPath to set
     */
    public void setParentPath(String parentPath)
    {
        this.parentPath = parentPath;
    }

    /**
     * Returns the file.
     * @return the file
     */
    public Document getZipFile()
    {
        return zipFile;
    }

    /**
     * Sets the file.
     * @param file the file to set
     */
    public void setZipFile(Document file)
    {
        this.zipFile = file;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Messages getMsgs()
    {
        return super.getMsgs();
    }

    public String getMessage(String key, String arg)
    {
        return super.getMsgs().get(key, new String[]{arg });
    }

    /**
     * Returns the installed media module version.
     * @return version as string.
     */
    public String getModuleVersion()
    {
        return MediaEl.module().getVersion();
    }

}
