/* 
-*- coding: latin-1 -*-

This file is part of RefactorErl.

RefactorErl is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

RefactorErl 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with RefactorErl.  If not, see <http://plc.inf.elte.hu/erlang/>.

The Original Code is RefactorErl.

The Initial Developer of the Original Code is Eötvös Loránd University.
Portions created  by Eötvös Loránd University and ELTE-Soft Ltd.
are Copyright 2007-2025 Eötvös Loránd University, ELTE-Soft Ltd.
and Ericsson Hungary. All Rights Reserved.
*/

package com.refactorerl.ui.presentation.codebrowser;

import java.io.ByteArrayInputStream;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPersistableElement;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;

import com.refactorerl.ui.logic.GetFileFromServerRequest;
import com.refactorerl.ui.presentation.Activator;

/**
 * Acquires the contents of the remote file on the supplied remote location, and
 * creates a temporary local copy in the preferred temp directory. Finally it
 * wraps a FileEditorInput opened on this local file. Constructor is private,
 * use the createRemoteTemporaryFileEditorInput(String remoteFilePath) factory
 * method.
 * 
 * @author Daniel Lukacs, 2014 ELTE IK
 *
 */
public class RemoteTemporaryFileEditorInput implements IFileEditorInput {
	private String remoteFilePath;
	private FileEditorInput editorInput;

	FileEditorInput getEditorInput() {
		return editorInput;
	}

	public static RemoteTemporaryFileEditorInput createRemoteTemporaryFileEditorInput(String remoteFilePath) {
		try {
			return new RemoteTemporaryFileEditorInput(remoteFilePath);
		} catch (CoreException e) {
			Activator.showErrorDialog(e, PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
			return null;
		}
	}

	/**
	 * Creates the folder structure inside the supplied IProject, mirroring the IPath supplied in the arguments. 
	 * @param project
	 * @param relativeDirs
	 * @throws CoreException
	 */
	public static void createFolders(IProject project, IPath relativeDirs) throws CoreException {

		int segCount = relativeDirs.segmentCount();
		for (int i = segCount - 1; i >= 0; i--) {
			IFolder folder = project.getFolder(relativeDirs.removeLastSegments(i));
			if (!folder.exists())
				folder.create(false, true, null);
		}

	}

	/**
	 * Requests the contents of the file specified by the supplied path string from RefactorErl and creates a temporary file with the same content in 
	 * the External Files project. This is necessary because some text editors (for example org.erlide.ui.editors.erl.ErlangEditor, org.erlide.ui.editors.scratchpad.erlangScratchPad)
	 * build on the services provided by FileEditorInput which needs a local workspace resource.    
	 * @param remoteFilePath
	 * @throws CoreException
	 */
	private RemoteTemporaryFileEditorInput(String remoteFilePath) throws CoreException {
		this.remoteFilePath = remoteFilePath;

		byte[] contents = Activator.executeRequest(new GetFileFromServerRequest(remoteFilePath, Activator.getProxy(),
				null), PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());

		// contents = Activator.executeRequest(new
		// FileContentRequest(remoteFilePath,
		// Activator.getProxy(), null),
		// PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());

		final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();

		IProject project = root.getProject("External Files"); //$NON-NLS-1$
		if (!project.exists())
			project.create(null);
		if (!project.isOpen())
			project.open(null);

		final Path fullpath = new Path(Activator.getLocalTempStorePrefix() + new Path(remoteFilePath));

		createFolders(project, fullpath.removeLastSegments(1));

		IFile file = project.getFile(fullpath);

		if (file.exists())
			file.delete(false, null);

		if (!file.exists())
			file.create(new ByteArrayInputStream(contents), false, null);

		file.getResourceAttributes().setReadOnly(true); // the temp file wont be
														// saveable this way
		editorInput = new FileEditorInput(file);
	}

	public void refresh() throws CoreException {
		byte[] contents = Activator.executeRequest(new GetFileFromServerRequest(remoteFilePath, Activator.getProxy(),
				null), PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());

		getFile().setContents(new ByteArrayInputStream(contents), false, false, null);
		getFile().refreshLocal(IFile.DEPTH_INFINITE, null);
		getFile().getResourceAttributes().setReadOnly(true);
	}

	public IPath getRemoteFilePath() {
		return new Path(remoteFilePath);
	}

	@Override
	public IStorage getStorage() throws CoreException {

		return editorInput.getStorage();
	}

	@Override
	public boolean exists() {
		return editorInput.exists();
	}

	@Override
	public ImageDescriptor getImageDescriptor() {
		return editorInput.getImageDescriptor();
	}

	@Override
	public String getName() {

		return editorInput.getName();
	}

	@Override
	public IPersistableElement getPersistable() {
		return null;
	}

	@Override
	public String getToolTipText() {
		return editorInput.getToolTipText();
	}

	@Override
	public Object getAdapter(Class adapter) {
		return editorInput.getAdapter(adapter);
	}

	@Override
	public IFile getFile() {
		return editorInput.getFile();
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof RemoteTemporaryFileEditorInput))
			return false;
		RemoteTemporaryFileEditorInput other = (RemoteTemporaryFileEditorInput) obj;
		return other.getEditorInput().equals(this.getEditorInput());

	}

}
