/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * Licensed 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.jetbrains.idea.eclipse.config;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.impl.storage.FileSet;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.HashMap;
import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.output.EclipseJDOMUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.*;
import java.util.*;

public class CachedXmlDocumentSet implements FileSet {
  protected final Map<String, String> nameToDir = new HashMap<String, String>();
  protected final Map<String, Document> savedContent = new HashMap<String, Document>();
  protected final Map<String, Document> modifiedContent = new HashMap<String, Document>();
  protected final Set<String> deletedContent = new HashSet<String>();
  private final Project project;

  public CachedXmlDocumentSet(Project project) {
    this.project = project;
  }

  public Document read(final String name) throws IOException, JDOMException {
    return read(name, true);
  }

  public Document read(final String name, final boolean refresh) throws IOException, JDOMException {
    return (Document)load(name, refresh).clone();
  }

  public void write(Document document, String name) throws IOException {
    update((Document)document.clone(), name);
  }

  public String getParent(final String name) {
    return nameToDir.get(name);
  }

  public void register(final String name, final String path) {
    nameToDir.put(name, path);
  }

  protected void assertKnownName(final String name) {
    assert nameToDir.containsKey(name) : name;
  }

  public boolean exists(String name) {
    assertKnownName(name);
    return !deletedContent.contains(name) && getVFile(name, false) != null;
  }

  @Nullable
  protected VirtualFile getVFile(final String name) {
    return getVFile(name, true);
  }

  @Nullable
  protected VirtualFile getVFile(final String name, boolean refresh) {
    final VirtualFile file = LocalFileSystem.getInstance().findFileByIoFile(new File(getParent(name), name));
    if (file != null && refresh) {
      file.refresh(false, true);
      if (!file.isValid()) return null;
    }
    return file;
  }

  @NotNull
  private VirtualFile getOrCreateVFile(final String name) throws IOException {
    final VirtualFile vFile = getVFile(name);
    if (vFile != null) {
      return vFile;
    }
    else {
      final VirtualFile vDir = LocalFileSystem.getInstance().findFileByIoFile(new File(getParent(name)));
      if (vDir == null) {
        throw new IOException(name + ": file not found");
      }
      final IOException[] ex = new IOException[1];
      final VirtualFile file = ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
        public VirtualFile compute() {
          try {
            return vDir.createChildData(this, name);
          }
          catch (IOException e) {
            ex[0] = e;
            return null;
          }
        }
      });
      if (ex[0] != null) throw ex[0];
      return file;
    }
  }

  protected Document load(final String name, boolean refresh) throws IOException, JDOMException {
    assertKnownName(name);
    final Document logical = modifiedContent.get(name);
    if (logical != null) {
      return logical;
    }

    Document physical = savedContent.get(name);
    if (physical == null) {
      final VirtualFile vFile = deletedContent.contains(name) ? null : getVFile(name, refresh);
      if (vFile == null) {
        throw new IOException(name + ": file does not exist");
      }
      final InputStream is = vFile.getInputStream();
      try {
        physical = JDOMUtil.loadDocument(is);
      }
      finally {
        is.close();
      }
      savedContent.put(name, physical);
    }
    return physical;

  }

  public void preload() {
    for (String key : nameToDir.keySet()) {
      try {
        load(key, true);
      }
      catch (IOException ignore) {
      }
      catch (JDOMException ignore) {
      }
    }
  }

  public void update(Document content, final String name) {
    assertKnownName(name);
    modifiedContent.put(name, content);
    deletedContent.remove(name);
  }

  public void delete(String name) {
    modifiedContent.remove(name);
    savedContent.remove(name);
    deletedContent.add(name);
    //nameToDir.remove(name);
  }

  public void listFiles(final List<VirtualFile> list) {
    Set<String> existingFiles = new HashSet<String>(savedContent.keySet());
    existingFiles.addAll(modifiedContent.keySet());
    for (String key : existingFiles) {
      try {
        if(getVFile(key)==null) {
          savedContent.remove(key); // deleted on disk
        }
        list.add(getOrCreateVFile(key));
      }
      catch (IOException ignore) {
      }
    }
    Set<String> newFiles = new HashSet<String>(nameToDir.keySet());
    newFiles.removeAll(existingFiles);
    for (String name : newFiles) {
      VirtualFile vFile = getVFile(name);
      if (vFile != null) {
        list.add(vFile);
      }
    }
  }

  @Override
  public void listModifiedFiles(List<VirtualFile> list) {
    for (String key : modifiedContent.keySet()) {
      try {
        if (hasChanged(key)) {
          list.add(getOrCreateVFile(key));
        }
      }
      catch (IOException ignore) {
      }
    }
  }

  public boolean hasChanged() {
    for (String key : modifiedContent.keySet()) {
      if (hasChanged(key)) {
        return true;
      }
    }
    return !deletedContent.isEmpty();
  }

  private boolean hasChanged(final String key) {
    final Document content = modifiedContent.get(key);
    final Document physical1 = content == null ? null : content;
    final Document physical2 = savedContent.get(key);
    if (physical1 != null && physical2 != null) {
      return !JDOMUtil.areDocumentsEqual(physical1, physical2);
    }
    return physical1 != physical2;
  }

  public void commit() throws IOException {
    for (String key : modifiedContent.keySet()) {
      if (hasChanged(key)) {
        final Document content = modifiedContent.get(key);
        if (content != null) {
          final Writer writer = new OutputStreamWriter(getOrCreateVFile(key).getOutputStream(this), "UTF-8");
          try {
            EclipseJDOMUtil.output(content, writer, project);
          }
          finally {
            writer.close();
          }
          savedContent.put(key, content);
        }
      }
    }

    ApplicationManager.getApplication().runWriteAction(new Runnable() {
      public void run() {
        for (String deleted : deletedContent) {
          VirtualFile file = getVFile(deleted);
          if (file != null) {
            try {
              file.delete(this);
            }
            catch (IOException ignore) {
            }
          }
        }
        deletedContent.clear();
      }
    });
  }


}
