/*
 * Copyright 2000-2014 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.
 */

/*
 * @author max
 */
package com.intellij.openapi.vfs.newvfs.persistent;

import com.intellij.openapi.Forceable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
import com.intellij.openapi.util.io.ByteSequence;
import com.intellij.openapi.util.io.FileAttributes;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.newvfs.FileAttribute;
import com.intellij.openapi.vfs.newvfs.impl.FileNameCache;
import com.intellij.util.ArrayUtil;
import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ConcurrentHashMap;
import com.intellij.util.containers.IntArrayList;
import com.intellij.util.io.*;
import com.intellij.util.io.DataOutputStream;
import com.intellij.util.io.storage.*;
import gnu.trove.TIntArrayList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import static com.intellij.util.io.IOUtil.deleteAllFilesStartingWith;

@SuppressWarnings({"PointlessArithmeticExpression", "HardCodedStringLiteral"})
public class FSRecords implements Forceable {
  private static final Logger LOG = Logger.getInstance("#com.intellij.vfs.persistent.FSRecords");

  public static final boolean weHaveContentHashes = SystemProperties.getBooleanProperty("idea.share.contents", true);
  public static final boolean lazyVfsDataCleaning = SystemProperties.getBooleanProperty("idea.lazy.vfs.data.cleaning", true);
  private static final int VERSION = 20 + (weHaveContentHashes ? 0x10:0) + (IOUtil.ourByteBuffersUseNativeByteOrder ? 0x37:0);

  private static final int PARENT_OFFSET = 0;
  private static final int PARENT_SIZE = 4;
  private static final int NAME_OFFSET = PARENT_OFFSET + PARENT_SIZE;
  private static final int NAME_SIZE = 4;
  private static final int FLAGS_OFFSET = NAME_OFFSET + NAME_SIZE;
  private static final int FLAGS_SIZE = 4;
  private static final int ATTR_REF_OFFSET = FLAGS_OFFSET + FLAGS_SIZE;
  private static final int ATTR_REF_SIZE = 4;
  private static final int CONTENT_OFFSET = ATTR_REF_OFFSET + ATTR_REF_SIZE;
  private static final int CONTENT_SIZE = 4;
  private static final int TIMESTAMP_OFFSET = CONTENT_OFFSET + CONTENT_SIZE;
  private static final int TIMESTAMP_SIZE = 8;
  private static final int MOD_COUNT_OFFSET = TIMESTAMP_OFFSET + TIMESTAMP_SIZE;
  private static final int MOD_COUNT_SIZE = 4;
  private static final int LENGTH_OFFSET = MOD_COUNT_OFFSET + MOD_COUNT_SIZE;
  private static final int LENGTH_SIZE = 8;

  private static final int RECORD_SIZE = LENGTH_OFFSET + LENGTH_SIZE;

  private static final byte[] ZEROES = new byte[RECORD_SIZE];

  private static final int HEADER_VERSION_OFFSET = 0;
  //private static final int HEADER_RESERVED_4BYTES_OFFSET = 4; // reserved
  private static final int HEADER_GLOBAL_MOD_COUNT_OFFSET = 8;
  private static final int HEADER_CONNECTION_STATUS_OFFSET = 12;
  private static final int HEADER_TIMESTAMP_OFFSET = 16;
  private static final int HEADER_SIZE = HEADER_TIMESTAMP_OFFSET + 8;

  private static final int CONNECTED_MAGIC = 0x12ad34e4;
  private static final int SAFELY_CLOSED_MAGIC = 0x1f2f3f4f;
  private static final int CORRUPTED_MAGIC = 0xabcf7f7f;

  private static final String CHILDREN_ATT = "FsRecords.DIRECTORY_CHILDREN";

  private static final ReentrantReadWriteLock.ReadLock r;
  private static final ReentrantReadWriteLock.WriteLock w;

  private static volatile int ourLocalModificationCount = 0;
  private static volatile boolean ourIsDisposed;

  private static final int FREE_RECORD_FLAG = 0x100;
  private static final int ALL_VALID_FLAGS = PersistentFS.ALL_VALID_FLAGS | FREE_RECORD_FLAG;

  static {
    //noinspection ConstantConditions
    assert HEADER_SIZE <= RECORD_SIZE;

    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    r = lock.readLock();
    w = lock.writeLock();
  }

  static void writeAttributesToRecord(int id, int parentId, FileAttributes attributes, String name) {
    try {
      w.lock();
      setName(id, name);

      setTimestamp(id, attributes.lastModified);
      setLength(id, attributes.isDirectory() ? -1L : attributes.length);

      setFlags(id, (attributes.isDirectory() ? PersistentFS.IS_DIRECTORY_FLAG : 0) |
                             (attributes.isWritable() ? 0 : PersistentFS.IS_READ_ONLY) |
                             (attributes.isSymLink() ? PersistentFS.IS_SYMLINK : 0) |
                             (attributes.isSpecial() ? PersistentFS.IS_SPECIAL : 0) |
                             (attributes.isHidden() ? PersistentFS.IS_HIDDEN : 0), true);
      setParent(id, parentId);
    } catch (Throwable e) {
      throw DbConnection.handleError(e);
    } finally {
      w.unlock();
    }
  }

  static class DbConnection {
    private static boolean ourInitialized;
    private static final ConcurrentHashMap<String, Integer> myAttributeIds = new ConcurrentHashMap<String, Integer>();

    private static PersistentStringEnumerator myNames;
    private static Storage myAttributes;
    private static RefCountingStorage myContents;
    private static ResizeableMappedFile myRecords;
    private static PersistentBTreeEnumerator<byte[]> myContentHashesEnumerator;
    private static final TIntArrayList myFreeRecords = new TIntArrayList();

    private static boolean myDirty = false;
    private static ScheduledFuture<?> myFlushingFuture;
    private static boolean myCorrupted = false;

    private static final AttrPageAwareCapacityAllocationPolicy REASONABLY_SMALL = new AttrPageAwareCapacityAllocationPolicy();


    public static void connect() {
      try {
        w.lock();
        if (!ourInitialized) {
          init();
          setupFlushing();
          ourInitialized = true;
        }
      }
      finally {
        w.unlock();
      }
    }

    private static void scanFreeRecords() {
      final int filelength = (int)myRecords.length();
      LOG.assertTrue(filelength % RECORD_SIZE == 0, "invalid file size: " + filelength);

      int count = filelength / RECORD_SIZE;
      for (int n = 2; n < count; n++) {
        if ((getFlags(n) & FREE_RECORD_FLAG) != 0) {
          myFreeRecords.add(n);
        }
      }
    }

    static int getFreeRecord() {
      if (myFreeRecords.isEmpty()) return 0;
      return myFreeRecords.remove(myFreeRecords.size() - 1);
    }

    private static void createBrokenMarkerFile(@Nullable Throwable reason) {
      final File brokenMarker = getCorruptionMarkerFile();

      try {
        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        final PrintStream stream = new PrintStream(out);
        try {
          new Exception().printStackTrace(stream);
          if (reason != null) {
            stream.print("\nReason:\n");
            reason.printStackTrace(stream);
          }
        }
        finally {
          stream.close();
        }
        LOG.info("Creating VFS corruption marker; Trace=\n" + out.toString());

        final FileWriter writer = new FileWriter(brokenMarker);
        try {
          writer.write("These files are corrupted and must be rebuilt from the scratch on next startup");
        }
        finally {
          writer.close();
        }
      }
      catch (IOException e) {
        // No luck.
      }
    }

    private static File getCorruptionMarkerFile() {
      return new File(basePath(), "corruption.marker");
    }

    private static void init() {
      final File basePath = basePath();
      basePath.mkdirs();

      final File namesFile = new File(basePath, "names.dat");
      final File attributesFile = new File(basePath, "attrib.dat");
      final File contentsFile = new File(basePath, "content.dat");
      final File contentsHashesFile = new File(basePath, "contentHashes.dat");
      final File recordsFile = new File(basePath, "records.dat");

      if (!namesFile.exists()) {
        invalidateIndex();
      }

      try {
        if (getCorruptionMarkerFile().exists()) {
          invalidateIndex();
          throw new IOException("Corruption marker file found");
        }

        PagedFileStorage.StorageLockContext storageLockContext = new PagedFileStorage.StorageLockContext(false);
        myNames = new PersistentStringEnumerator(namesFile, storageLockContext);
        myAttributes = new Storage(attributesFile.getCanonicalPath(), REASONABLY_SMALL);
        myContents = new RefCountingStorage(contentsFile.getCanonicalPath(), CapacityAllocationPolicy.FIVE_PERCENT_FOR_GROWTH); // sources usually zipped with 4x ratio
        myContentHashesEnumerator = weHaveContentHashes ? new ContentHashesUtil.HashEnumerator(contentsHashesFile, storageLockContext): null;
        boolean aligned = PagedFileStorage.BUFFER_SIZE % RECORD_SIZE == 0;
        assert aligned; // for performance
        myRecords = new ResizeableMappedFile(recordsFile, 20 * 1024, storageLockContext,
                                             PagedFileStorage.BUFFER_SIZE, aligned, IOUtil.ourByteBuffersUseNativeByteOrder);

        if (myRecords.length() == 0) {
          cleanRecord(0); // Clean header
          cleanRecord(1); // Create root record
          setCurrentVersion();
        }

        if (getVersion() != VERSION) {
          throw new IOException("FS repository version mismatch");
        }

        if (myRecords.getInt(HEADER_CONNECTION_STATUS_OFFSET) != SAFELY_CLOSED_MAGIC) {
          throw new IOException("FS repository wasn't safely shut down");
        }
        markDirty();
        scanFreeRecords();
      }
      catch (Exception e) { // IOException, IllegalArgumentException
        LOG.info("Filesystem storage is corrupted or does not exist. [Re]Building. Reason: " + e.getMessage());
        try {
          closeFiles();

          boolean deleted = FileUtil.delete(getCorruptionMarkerFile());
          deleted &= deleteAllFilesStartingWith(namesFile);
          deleted &= AbstractStorage.deleteFiles(attributesFile.getCanonicalPath());
          deleted &= AbstractStorage.deleteFiles(contentsFile.getCanonicalPath());
          deleted &= deleteAllFilesStartingWith(contentsHashesFile);
          deleted &= deleteAllFilesStartingWith(recordsFile);

          if (!deleted) {
            throw new IOException("Cannot delete filesystem storage files");
          }
        }
        catch (final IOException e1) {
          final Runnable warnAndShutdown = new Runnable() {
            @Override
            public void run() {
              if (ApplicationManager.getApplication().isUnitTestMode()) {
                //noinspection CallToPrintStackTrace
                e1.printStackTrace();
              }
              else {
                final String message = "Files in " + basePath.getPath() + " are locked.\n" +
                                       ApplicationNamesInfo.getInstance().getProductName() + " will not be able to start up.";
                if (!ApplicationManager.getApplication().isHeadlessEnvironment()) {
                  JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), message, "Fatal Error", JOptionPane.ERROR_MESSAGE);
                }
                else {
                  //noinspection UseOfSystemOutOrSystemErr
                  System.err.println(message);
                }
              }
              Runtime.getRuntime().halt(1);
            }
          };

          if (EventQueue.isDispatchThread()) {
            warnAndShutdown.run();
          }
          else {
            //noinspection SSBasedInspection
            SwingUtilities.invokeLater(warnAndShutdown);
          }

          throw new RuntimeException("Can't rebuild filesystem storage ", e1);
        }

        init();
      }
    }

    private static void invalidateIndex() {
      LOG.info("Marking VFS as corrupted");
      final File indexRoot = PathManager.getIndexRoot();
      if (indexRoot.exists()) {
        final String[] children = indexRoot.list();
        if (children != null && children.length > 0) {
          // create index corruption marker only if index directory exists and is non-empty
          // It is incorrect to consider non-existing indices "corrupted"
          FileUtil.createIfDoesntExist(new File(PathManager.getIndexRoot(), "corruption.marker"));
        }
      }
    }

    private static File basePath() {
      return new File(getCachesDir());
    }

    private static String getCachesDir() {
      String dir = System.getProperty("caches_dir");
      return dir == null ? PathManager.getSystemPath() + "/caches/" : dir;
    }

    private static void markDirty() {
      if (!myDirty) {
        myDirty = true;
        myRecords.putInt(HEADER_CONNECTION_STATUS_OFFSET, CONNECTED_MAGIC);
      }
    }

    private static void setupFlushing() {
      myFlushingFuture = FlushingDaemon.everyFiveSeconds(new Runnable() {
        int lastModCount = 0;

        @Override
        public void run() {
          if (lastModCount == ourLocalModificationCount) {
            flushSome();
          }
          lastModCount = ourLocalModificationCount;
        }
      });
    }

    public static void force() {
      try {
        w.lock();
        if (myRecords != null) {
          markClean();
        }
        if (myNames != null) {
          myNames.force();
          myAttributes.force();
          myContents.force();
          if (myContentHashesEnumerator != null) myContentHashesEnumerator.force();
          myRecords.force();
        }
      }
      finally {
        w.unlock();
      }
    }

    public static void flushSome() {
      if (!isDirty() || HeavyProcessLatch.INSTANCE.isRunning()) return;

      try {
        w.lock();
        if (myFlushingFuture == null) {
          return; // avoid NPE when close has already taken place
        }
        myNames.force();

        final boolean attribsFlushed = myAttributes.flushSome();
        final boolean contentsFlushed = myContents.flushSome();
        if (myContentHashesEnumerator != null) myContentHashesEnumerator.force();
        if (attribsFlushed && contentsFlushed) {
          markClean();
          myRecords.force();
        }
      }
      finally {
        w.unlock();
      }
    }

    public static boolean isDirty() {
      return myDirty || myNames.isDirty() || myAttributes.isDirty() || myContents.isDirty() || myRecords.isDirty() ||
             (myContentHashesEnumerator != null && myContentHashesEnumerator.isDirty());
    }


    private static int getVersion() {
      final int recordsVersion = myRecords.getInt(HEADER_VERSION_OFFSET);
      if (myAttributes.getVersion() != recordsVersion || myContents.getVersion() != recordsVersion) return -1;

      return recordsVersion;
    }

    public static long getTimestamp() {
      return myRecords.getLong(HEADER_TIMESTAMP_OFFSET);
    }

    private static void setCurrentVersion() {
      myRecords.putInt(HEADER_VERSION_OFFSET, VERSION);
      myRecords.putLong(HEADER_TIMESTAMP_OFFSET, System.currentTimeMillis());
      myAttributes.setVersion(VERSION);
      myContents.setVersion(VERSION);
      myRecords.putInt(HEADER_CONNECTION_STATUS_OFFSET, SAFELY_CLOSED_MAGIC);
    }

    static void cleanRecord(int id) {
      myRecords.put(id * RECORD_SIZE, ZEROES, 0, RECORD_SIZE);
    }

    public static PersistentStringEnumerator getNames() {
      return myNames;
    }

    private static void closeFiles() throws IOException {
      if (myFlushingFuture != null) {
        myFlushingFuture.cancel(false);
        myFlushingFuture = null;
      }

      if (myNames != null) {
        myNames.close();
        myNames = null;
      }

      if (myAttributes != null) {
        Disposer.dispose(myAttributes);
        myAttributes = null;
      }

      if (myContents != null) {
        Disposer.dispose(myContents);
        myContents = null;
      }

      if (myContentHashesEnumerator != null) {
        myContentHashesEnumerator.close();
        myContentHashesEnumerator = null;
      }

      if (myRecords != null) {
        markClean();
        myRecords.close();
        myRecords = null;
      }
      ourInitialized = false;
    }

    private static void markClean() {
      if (myDirty) {
        myDirty = false;
        myRecords.putInt(HEADER_CONNECTION_STATUS_OFFSET, myCorrupted ? CORRUPTED_MAGIC : SAFELY_CLOSED_MAGIC);
      }
    }

    private static int getAttributeId(@NotNull String attId) throws IOException {
      Integer integer = myAttributeIds.get(attId);
      if (integer != null) return integer.intValue();
      int enumeratedId = myNames.enumerate(attId);
      integer = myAttributeIds.putIfAbsent(attId, enumeratedId);
      return integer == null ? enumeratedId:  integer.intValue();
    }

    private static RuntimeException handleError(final Throwable e) {
      if (!ourIsDisposed) {
        // No need to forcibly mark VFS corrupted if it is already shut down
        if (!myCorrupted) {
          createBrokenMarkerFile(e);
          myCorrupted = true;
          force();
        }
      }

      return new RuntimeException(e);
    }

    private static class AttrPageAwareCapacityAllocationPolicy extends CapacityAllocationPolicy {
      boolean myAttrPageRequested;

      @Override
      public int calculateCapacity(int requiredLength) {   // 20% for growth
        return Math.max(myAttrPageRequested ? 8:32, Math.min((int)(requiredLength * 1.2), (requiredLength / 1024 + 1) * 1024));
      }
    }
  }

  public FSRecords() {
  }

  public static void connect() {
    DbConnection.connect();
  }

  public static long getCreationTimestamp() {
    try {
      r.lock();
      return DbConnection.getTimestamp();
    }
    finally {
      r.unlock();
    }
  }

  private static ResizeableMappedFile getRecords() {
    return DbConnection.myRecords;
  }

  private static PersistentBTreeEnumerator<byte[]> getContentHashesEnumerator() {
    return DbConnection.myContentHashesEnumerator;
  }

  private static RefCountingStorage getContentStorage() {
    return DbConnection.myContents;
  }

  private static Storage getAttributesStorage() {
    return DbConnection.myAttributes;
  }

  public static PersistentStringEnumerator getNames() {
    return DbConnection.getNames();
  }

  public static int createRecord() {
    try {
      w.lock();
      DbConnection.markDirty();

      final int free = DbConnection.getFreeRecord();
      if (free == 0) {
        final int fileLength = length();
        LOG.assertTrue(fileLength % RECORD_SIZE == 0);
        int newRecord = fileLength / RECORD_SIZE;
        DbConnection.cleanRecord(newRecord);
        assert fileLength + RECORD_SIZE == length();
        return newRecord;
      }
      else {
        if (lazyVfsDataCleaning) deleteContentAndAttributes(free);
        DbConnection.cleanRecord(free);
        return free;
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
    finally {
      w.unlock();
    }
  }

  private static int length() {
    return (int)getRecords().length();
  }
  public static int getMaxId() {
    try {
      r.lock();
      return length()/RECORD_SIZE;
    }
    finally {
      r.unlock();
    }

  }

  static void deleteRecordRecursively(int id) {
    try {
      w.lock();
      incModCount(id);
      if (lazyVfsDataCleaning) {
        markAsDeletedRecursively(id);
      } else {
        doDeleteRecursively(id);
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
    finally {
      w.unlock();
    }
  }

  private static void markAsDeletedRecursively(final int id) {
    for (int subrecord : list(id)) {
      markAsDeletedRecursively(subrecord);
    }

    markAsDeleted(id);
  }

  private static void markAsDeleted(final int id) {
    try {
      w.lock();
      DbConnection.markDirty();
      addToFreeRecordsList(id);
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
    finally {
      w.unlock();
    }
  }

  private static void doDeleteRecursively(final int id) {
    for (int subrecord : list(id)) {
      doDeleteRecursively(subrecord);
    }

    deleteRecord(id);
  }

  private static void deleteRecord(final int id) {
    try {
      w.lock();
      DbConnection.markDirty();
      deleteContentAndAttributes(id);

      DbConnection.cleanRecord(id);
      addToFreeRecordsList(id);
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
    finally {
      w.unlock();
    }
  }

  private static void deleteContentAndAttributes(int id) throws IOException {
    int content_page = getContentRecordId(id);
    if (content_page != 0) {
      if (weHaveContentHashes) {
        getContentStorage().releaseRecord(content_page, false);
      } else {
        getContentStorage().releaseRecord(content_page);
      }
    }

    int att_page = getAttributeRecordId(id);
    if (att_page != 0) {
      final DataInputStream attStream = getAttributesStorage().readStream(att_page);
      while (attStream.available() > 0) {
        DataInputOutputUtil.readINT(attStream); // Attribute ID;
        int attAddress = DataInputOutputUtil.readINT(attStream);
        getAttributesStorage().deleteRecord(attAddress);
      }
      attStream.close();
      getAttributesStorage().deleteRecord(att_page);
    }
  }

  private static void addToFreeRecordsList(int id) {
    // DbConnection.addFreeRecord(id); // do not add fileId to free list until restart
    setFlags(id, FREE_RECORD_FLAG, false);
  }

  static int[] listRoots() {
    try {
      try {
        r.lock();
        final DataInputStream input = readAttribute(1, CHILDREN_ATT);
        if (input == null) return ArrayUtil.EMPTY_INT_ARRAY;

        try {
          final int count = DataInputOutputUtil.readINT(input);
          int[] result = ArrayUtil.newIntArray(count);
          for (int i = 0; i < count; i++) {
            DataInputOutputUtil.readINT(input); // Name
            result[i] = DataInputOutputUtil.readINT(input); // Id
          }
          return result;
        }
        finally {
          input.close();
        }
      }
      finally {
        r.unlock();
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  @Override
  public void force() {
    DbConnection.force();
  }

  @Override
  public boolean isDirty() {
    return DbConnection.isDirty();
  }

  public static int findRootRecord(@NotNull String rootUrl) {
    try {
      try {
        w.lock();
        DbConnection.markDirty();
        final int root = getNames().enumerate(rootUrl);

        final DataInputStream input = readAttribute(1, CHILDREN_ATT);
        int[] names = ArrayUtil.EMPTY_INT_ARRAY;
        int[] ids = ArrayUtil.EMPTY_INT_ARRAY;

        if (input != null) {
          try {
            final int count = DataInputOutputUtil.readINT(input);
            names = ArrayUtil.newIntArray(count);
            ids = ArrayUtil.newIntArray(count);
            for (int i = 0; i < count; i++) {
              final int name = DataInputOutputUtil.readINT(input);
              final int id = DataInputOutputUtil.readINT(input);
              if (name == root) {
                return id;
              }

              names[i] = name;
              ids[i] = id;
            }
          }
          finally {
            input.close();
          }
        }

        final DataOutputStream output = writeAttribute(1, CHILDREN_ATT, false);
        int id;
        try {
          id = createRecord();
          DataInputOutputUtil.writeINT(output, names.length + 1);
          for (int i = 0; i < names.length; i++) {
            DataInputOutputUtil.writeINT(output, names[i]);
            DataInputOutputUtil.writeINT(output, ids[i]);
          }
          DataInputOutputUtil.writeINT(output, root);
          DataInputOutputUtil.writeINT(output, id);
        }
        finally {
          output.close();
        }

        return id;
      }
      finally {
        w.unlock();
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  public static void deleteRootRecord(int id) {
    try {
      try {
        w.lock();
        DbConnection.markDirty();
        final DataInputStream input = readAttribute(1, CHILDREN_ATT);
        assert input != null;
        int count;
        int[] names;
        int[] ids;
        try {
          count = DataInputOutputUtil.readINT(input);

          names = ArrayUtil.newIntArray(count);
          ids = ArrayUtil.newIntArray(count);
          for (int i = 0; i < count; i++) {
            names[i] = DataInputOutputUtil.readINT(input);
            ids[i] = DataInputOutputUtil.readINT(input);
          }
        }
        finally {
          input.close();
        }

        final int index = ArrayUtil.find(ids, id);
        assert index >= 0;

        names = ArrayUtil.remove(names, index);
        ids = ArrayUtil.remove(ids, index);

        final DataOutputStream output = writeAttribute(1, CHILDREN_ATT, false);
        try {
          DataInputOutputUtil.writeINT(output, count - 1);
          for (int i = 0; i < names.length; i++) {
            DataInputOutputUtil.writeINT(output, names[i]);
            DataInputOutputUtil.writeINT(output, ids[i]);
          }
        }
        finally {
          output.close();
        }
      }
      finally {
        w.unlock();
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  public static int[] list(int id) {
    try {
      r.lock();
      try {
        final DataInputStream input = readAttribute(id, CHILDREN_ATT);
        if (input == null) return ArrayUtil.EMPTY_INT_ARRAY;

        final int count = DataInputOutputUtil.readINT(input);
        final int[] result = ArrayUtil.newIntArray(count);
        for (int i = 0; i < count; i++) {
          int childId = DataInputOutputUtil.readINT(input);
          childId = childId >= 0 ? childId + id : -childId;
          result[i] = childId;
        }
        input.close();
        return result;
      }
      finally {
        r.unlock();
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  public static class NameId {
    public static final NameId[] EMPTY_ARRAY = new NameId[0];
    public final int id;
    public final CharSequence name;
    public final int nameId;

    public NameId(int id, int nameId, @NotNull CharSequence name) {
      this.id = id;
      this.nameId = nameId;
      this.name = name;
    }

    @Override
    public String toString() {
      return name + " (" + id + ")";
    }
  }

  @NotNull
  public static NameId[] listAll(int parentId) {
    try {
      r.lock();
      try {
        final DataInputStream input = readAttribute(parentId, CHILDREN_ATT);
        if (input == null) return NameId.EMPTY_ARRAY;

        int count = DataInputOutputUtil.readINT(input);
        NameId[] result = count == 0 ? NameId.EMPTY_ARRAY : new NameId[count];
        for (int i = 0; i < count; i++) {
          int id = DataInputOutputUtil.readINT(input);
          id = id >= 0 ? id + parentId : -id;
          int nameId = getNameId(id);
          result[i] = new NameId(id, nameId, FileNameCache.getVFileName(nameId));
        }
        input.close();
        return result;
      }
      finally {
        r.unlock();
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  public static boolean wereChildrenAccessed(int id) {
    try {
      r.lock();
      try {
        return findAttributePage(id, CHILDREN_ATT, false) != 0;
      } finally {
        r.unlock();
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  public static void updateList(int id, @NotNull int[] children) {
    try {
      w.lock();
      DbConnection.markDirty();
      final DataOutputStream record = writeAttribute(id, CHILDREN_ATT, false);
      DataInputOutputUtil.writeINT(record, children.length);
      for (int child : children) {
        if (child == id) {
          LOG.error("Cyclic parent child relations");
        }
        else {
          child = child > id ? child - id : -child;
          DataInputOutputUtil.writeINT(record, child);
        }
      }
      record.close();
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
    finally {
      w.unlock();
    }
  }

  private static void incModCount(int id) {
    DbConnection.markDirty();
    ourLocalModificationCount++;
    final int count = getModCount() + 1;
    getRecords().putInt(HEADER_GLOBAL_MOD_COUNT_OFFSET, count);

    int parent = id;
    int depth = 10000;
    while (parent != 0) {
      setModCount(parent, count);
      parent = getParent(parent);
      if (depth -- == 0) {
        LOG.error("Cyclic parent child relation? file: " + getName(id));
        return;
      }
    }
  }

  public static int getLocalModCount() {
    return ourLocalModificationCount; // This is volatile, only modified under Application.runWriteAction() lock.
  }

  public static int getModCount() {
    try {
      r.lock();
      return getRecords().getInt(HEADER_GLOBAL_MOD_COUNT_OFFSET);
    }
    finally {
      r.unlock();
    }
  }

  public static int getParent(int id) {
    try {
      r.lock();
      try {
        final int parentId = getRecordInt(id, PARENT_OFFSET);
        if (parentId == id) {
          LOG.error("Cyclic parent child relations in the database. id = " + id);
          return 0;
        }

        return parentId;
      }
      finally {
        r.unlock();
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  public static void setParent(int id, int parent) {
    if (id == parent) {
      LOG.error("Cyclic parent/child relations");
      return;
    }

    try {
      w.lock();
      incModCount(id);
      putRecordInt(id, PARENT_OFFSET, parent);
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
    finally {
      w.unlock();
    }
  }

  public static int getNameId(int id) {
    try {
      r.lock();
      try {
        return getRecordInt(id, NAME_OFFSET);
      }
      finally {
        r.unlock();
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  public static int getNameId(String name) {
    try {
      r.lock();
      try {
        return getNames().enumerate(name);
      }
      finally {
        r.unlock();
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  public static String getName(int id) {
    try {
      r.lock();
      try {
        final int nameId = getRecordInt(id, NAME_OFFSET);
        return nameId != 0 ? getNames().valueOf(nameId) : "";
      }
      finally {
        r.unlock();
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  public static String getNameByNameId(int nameId) {
    try {
      r.lock();
      try {
        return nameId != 0 ? getNames().valueOf(nameId) : "";
      }
      finally {
        r.unlock();
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  public static void setName(int id, String name) {
    try {
      w.lock();
      incModCount(id);
      putRecordInt(id, NAME_OFFSET, getNames().enumerate(name));
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
    finally {
      w.unlock();
    }
  }

  public static int getFlags(int id) {
    try {
      r.lock();
      return getRecordInt(id, FLAGS_OFFSET);
    }
    finally {
      r.unlock();
    }
  }

  public static void setFlags(int id, int flags, final boolean markAsChange) {
    try {
      w.lock();
      if (markAsChange) {
        incModCount(id);
      }
      putRecordInt(id, FLAGS_OFFSET, flags);
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
    finally {
      w.unlock();
    }
  }

  public static long getLength(int id) {
    try {
      r.lock();
      return getRecords().getLong(getOffset(id, LENGTH_OFFSET));
    }
    finally {
      r.unlock();
    }
  }

  public static void setLength(int id, long len) {
    try {
      w.lock();
      incModCount(id);
      getRecords().putLong(getOffset(id, LENGTH_OFFSET), len);
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
    finally {
      w.unlock();
    }
  }

  public static long getTimestamp(int id) {
    try {
      r.lock();
      return getRecords().getLong(getOffset(id, TIMESTAMP_OFFSET));
    }
    finally {
      r.unlock();
    }
  }

  public static void setTimestamp(int id, long value) {
    try {
      w.lock();
      incModCount(id);
      getRecords().putLong(getOffset(id, TIMESTAMP_OFFSET), value);
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
    finally {
      w.unlock();
    }
  }

  public static int getModCount(int id) {
    try {
      r.lock();
      return getRecordInt(id, MOD_COUNT_OFFSET);
    }
    finally {
      r.unlock();
    }
  }

  private static void setModCount(int id, int value) {
    putRecordInt(id, MOD_COUNT_OFFSET, value);
  }

  private static int getContentRecordId(int fileId) {
    return getRecordInt(fileId, CONTENT_OFFSET);
  }

  private static void setContentRecordId(int id, int value) {
    putRecordInt(id, CONTENT_OFFSET, value);
  }

  private static int getAttributeRecordId(int id) {
    return getRecordInt(id, ATTR_REF_OFFSET);
  }

  private static void setAttributeRecordId(int id, int value) {
    putRecordInt(id, ATTR_REF_OFFSET, value);
  }

  private static int getRecordInt(int id, int offset) {
    return getRecords().getInt(getOffset(id, offset));
  }

  private static void putRecordInt(int id, int offset, int value) {
    getRecords().putInt(getOffset(id, offset), value);
  }

  private static int getOffset(int id, int offset) {
    return id * RECORD_SIZE + offset;
  }

  @Nullable
  public static DataInputStream readContent(int fileId) {
    try {
      int page;
      try {
        r.lock();
        checkFileIsValid(fileId);

        page = getContentRecordId(fileId);
        if (page == 0) return null;
      }
      finally {
        r.unlock();
      }
      return getContentStorage().readStream(page);
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  @Nullable
  public static DataInputStream readContentById(int contentId) {
    try {
      return getContentStorage().readStream(contentId);
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  @Nullable
  public static DataInputStream readAttributeWithLock(int fileId, FileAttribute att) {
    try {
      synchronized (att.getId()) {
        try {
          r.lock();
          DataInputStream stream = readAttribute(fileId, att.getId());
          if (stream != null) {
            try {
              int actualVersion = DataInputOutputUtil.readINT(stream);
              if (actualVersion != att.getVersion()) {
                stream.close();
                return null;
              }
            }
            catch (IOException e) {
              stream.close();
              return null;
            }
          }
          return stream;
        }
        finally {
          r.unlock();
        }
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  // should be called under r or w lock
  @Nullable
  private static DataInputStream readAttribute(int fileId, String attId) throws IOException {
    int page = findAttributePage(fileId, attId, false);
    if (page == 0) return null;
    return getAttributesStorage().readStream(page);
  }

  private static int findAttributePage(int fileId, @NotNull String attrId, boolean toWrite) throws IOException {
    checkFileIsValid(fileId);

    Storage storage = getAttributesStorage();

    int encodedAttrId = DbConnection.getAttributeId(attrId);
    int recordId = getAttributeRecordId(fileId);

    if (recordId == 0) {
      if (!toWrite) return 0;

      recordId = storage.createNewRecord();
      setAttributeRecordId(fileId, recordId);
    }
    else {
      DataInputStream attrRefs = storage.readStream(recordId);
      try {
        while (attrRefs.available() > 0) {
          final int attIdOnPage = DataInputOutputUtil.readINT(attrRefs);
          final int attrAddress = DataInputOutputUtil.readINT(attrRefs);

          if (attIdOnPage == encodedAttrId) return attrAddress;
        }
      }
      finally {
        attrRefs.close();
      }
    }

    if (toWrite) {
      Storage.AppenderStream appender = storage.appendStream(recordId);
      DataInputOutputUtil.writeINT(appender, encodedAttrId);
      int attrAddress = storage.createNewRecord();
      DataInputOutputUtil.writeINT(appender, attrAddress);
      DbConnection.REASONABLY_SMALL.myAttrPageRequested = true;
      try {
        appender.close();
      } finally {
        DbConnection.REASONABLY_SMALL.myAttrPageRequested = false;
      }
      return attrAddress;
    }

    return 0;
  }

  private static void checkFileIsValid(int fileId) {
    assert fileId > 0 : fileId;
    // TODO: This assertion is a bit timey, will remove when bug is caught.
    if (!lazyVfsDataCleaning) {
      assert (getFlags(fileId) & FREE_RECORD_FLAG) == 0 : "Accessing attribute of a deleted page: " + fileId + ":" + getName(fileId);
    }
  }

  public static int acquireFileContent(int fileId) {
    try {
      w.lock();
      int record = getContentRecordId(fileId);
      if (record > 0) getContentStorage().acquireRecord(record);
      return record;
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
    finally {
      w.unlock();
    }
  }

  public static void releaseContent(int contentId) {
    try {
      w.lock();
      RefCountingStorage contentStorage = getContentStorage();
      if (weHaveContentHashes) {
        contentStorage.releaseRecord(contentId, false);
      } else {
        contentStorage.releaseRecord(contentId);
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    } finally {
      w.unlock();
    }
  }

  public static int getContentId(int fileId) {
    try {
      r.lock();
      try {
        return getContentRecordId(fileId);
      }
      finally {
        r.unlock();
      }
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  @NotNull
  public static DataOutputStream writeContent(int fileId, boolean readOnly) {
    return new ContentOutputStream(fileId, readOnly);
  }

  private static final MessageDigest myDigest = ContentHashesUtil.createHashDigest();

  public static void writeContent(int fileId, ByteSequence bytes, boolean readOnly) throws IOException {
    try {
      new ContentOutputStream(fileId, readOnly).writeBytes(bytes);
    } catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
  }

  public static int storeUnlinkedContent(byte[] bytes) {
    try {
      w.lock();
      int recordId;

      if (weHaveContentHashes) {
        recordId = findOrCreateContentRecord(bytes, 0, bytes.length);
        if (recordId > 0) return recordId;
        recordId = -recordId;
      } else {
        recordId = getContentStorage().acquireNewRecord();
      }
      AbstractStorage.StorageDataOutput output = getContentStorage().writeStream(recordId, true);
      output.write(bytes);
      output.close();
      return recordId;
    }
    catch (IOException e) {
      throw DbConnection.handleError(e);
    } finally {
      w.unlock();
    }
  }

  @NotNull
  public static DataOutputStream writeAttribute(final int fileId, @NotNull String attId, boolean fixedSize) {
    return new AttributeOutputStream(fileId, attId, fixedSize);
  }

  @NotNull
  public static DataOutputStream writeAttribute(final int fileId, @NotNull FileAttribute att) {
    DataOutputStream stream = writeAttribute(fileId, att.getId(), att.isFixedSize());
    try {
      DataInputOutputUtil.writeINT(stream, att.getVersion());
    }
    catch (IOException e) {
      throw new RuntimeException(e);
    }
    return stream;
  }

  private static class ContentOutputStream extends DataOutputStream {
    protected final int myFileId;
    protected final boolean myFixedSize;

    private ContentOutputStream(final int fileId, boolean readOnly) {
      super(new BufferExposingByteArrayOutputStream());
      myFileId = fileId;
      myFixedSize = readOnly;
    }

    @Override
    public void close() throws IOException {
      super.close();

      try {
        final BufferExposingByteArrayOutputStream _out = (BufferExposingByteArrayOutputStream)out;
        writeBytes(new ByteSequence(_out.getInternalBuffer(), 0, _out.size()));
      }
      catch (Throwable e) {
        throw DbConnection.handleError(e);
      }
    }

    public void writeBytes(ByteSequence bytes) throws IOException {
      int page;
      RefCountingStorage contentStorage = getContentStorage();
      final boolean fixedSize;
      try {
        w.lock();
        incModCount(myFileId);

        checkFileIsValid(myFileId);

        if (weHaveContentHashes) {
          page = findOrCreateContentRecord(bytes.getBytes(), bytes.getOffset(), bytes.getLength());

          incModCount(myFileId);
          checkFileIsValid(myFileId);

          setContentRecordId(myFileId, page > 0 ? page : -page);

          if (page > 0) return;
          page = -page;
          fixedSize = true;
        } else {
          page = getContentRecordId(myFileId);
          if (page == 0 || contentStorage.getRefCount(page) > 1) {
            page = contentStorage.acquireNewRecord();
            setContentRecordId(myFileId, page);
          }
          fixedSize = myFixedSize;
        }
      }
      finally {
        w.unlock();
      }

      contentStorage.writeBytes(page, bytes, fixedSize);
    }
  }

  private static final boolean DO_HARD_CONSISTENCY_CHECK = false;
  private static final boolean DUMP_STATISTICS = weHaveContentHashes;  // TODO: remove once not needed
  private static long totalContents, totalReuses, time;
  private static int contents, reuses;

  private static int findOrCreateContentRecord(byte[] bytes, int offset, int length) throws IOException {
    assert weHaveContentHashes;
    byte[] digest;

    long started = DUMP_STATISTICS ? System.nanoTime():0;
    myDigest.reset();
    myDigest.update(String.valueOf(length - offset).getBytes(Charset.defaultCharset()));
    myDigest.update("\0".getBytes(Charset.defaultCharset()));
    myDigest.update(bytes, offset, length);
    digest = myDigest.digest();
    long done = DUMP_STATISTICS ? System.nanoTime() - started : 0;
    time += done;

    ++contents;
    totalContents += length;

    if (DUMP_STATISTICS && (contents & 0x3FFF) == 0) {
      LOG.info("Contents:"+contents + " of " + totalContents + ", reuses:"+reuses + " of " + totalReuses + " for " + (time / 1000000));
    }
    PersistentBTreeEnumerator<byte[]> hashesEnumerator = getContentHashesEnumerator();
    final int largestId = hashesEnumerator.getLargestId();
    int page = hashesEnumerator.enumerate(digest);

    if (page <= largestId) {
      ++reuses;
      getContentStorage().acquireRecord(page);
      totalReuses += length;

      if (DO_HARD_CONSISTENCY_CHECK) {
        DataInputStream stream = getContentStorage().readStream(page);
        int i = offset;
        for(int c = 0; c < length; ++c) {
          if (stream.available() == 0) {
            assert false;
          }
          if (bytes[i++] != stream.readByte()) {
            assert false;
          }
        }
        if (stream.available() > 0) {
          assert false;
        }
      }
      return page;
    } else {
      int newRecord = getContentStorage().acquireNewRecord();
      if (page != newRecord) {
        assert false:"Unexpected content storage modification";
      }
      if (DO_HARD_CONSISTENCY_CHECK) {
        if (hashesEnumerator.enumerate(digest) != page) {
          assert false;
        }

        byte[] bytes1 = hashesEnumerator.valueOf(page);
        if (!Arrays.equals(digest, bytes1)) {
          assert false;
        }
      }
      return -page;
    }
  }

  private static class AttributeOutputStream extends DataOutputStream {
    private final String myAttributeId;
    private final int myFileId;
    private final boolean myFixedSize;

    private AttributeOutputStream(final int fileId, @NotNull String attributeId, boolean fixedSize) {
      super(new BufferExposingByteArrayOutputStream());
      myFileId = fileId;
      myFixedSize = fixedSize;
      myAttributeId = attributeId;
    }

    @Override
    public void close() throws IOException {
      super.close();

      try {
        synchronized (myAttributeId) {
          final BufferExposingByteArrayOutputStream _out = (BufferExposingByteArrayOutputStream)out;
          final int page;
          try {
            w.lock();
            incModCount(myFileId);
            page = findAttributePage(myFileId, myAttributeId, true);
          }
          finally {
            w.unlock();
          }
          getAttributesStorage().writeBytes(page, new ByteSequence(_out.getInternalBuffer(), 0, _out.size()), myFixedSize);
        }
      }
      catch (Throwable e) {
        throw DbConnection.handleError(e);
      }
    }
  }

  public static void dispose() {
    try {
      w.lock();
      DbConnection.force();
      DbConnection.closeFiles();
    }
    catch (Throwable e) {
      throw DbConnection.handleError(e);
    }
    finally {
      ourIsDisposed = true;
      w.unlock();
    }
  }

  public static void invalidateCaches() {
    DbConnection.createBrokenMarkerFile(null);
  }

  public static void checkSanity() {
    long t = System.currentTimeMillis();

    try {
      r.lock();
      final int fileLength = length();
      assert fileLength % RECORD_SIZE == 0;
      int recordCount = fileLength / RECORD_SIZE;

      IntArrayList usedAttributeRecordIds = new IntArrayList();
      IntArrayList validAttributeIds = new IntArrayList();
      for (int id = 2; id < recordCount; id++) {
        int flags = getFlags(id);
        LOG.assertTrue((flags & ~ALL_VALID_FLAGS) == 0, "Invalid flags: 0x" + Integer.toHexString(flags) + ", id: " + id);
        if ((flags & FREE_RECORD_FLAG) != 0) {
          LOG.assertTrue(DbConnection.myFreeRecords.contains(id), "Record, marked free, not in free list: " + id);
        }
        else {
          LOG.assertTrue(!DbConnection.myFreeRecords.contains(id), "Record, not marked free, in free list: " + id);
          checkRecordSanity(id, recordCount, usedAttributeRecordIds, validAttributeIds);
        }
      }
    }
    finally {
      r.unlock();
    }

    t = System.currentTimeMillis() - t;
    LOG.info("Sanity check took " + t + " ms");
  }

  private static void checkRecordSanity(final int id, final int recordCount, final IntArrayList usedAttributeRecordIds,
                                        final IntArrayList validAttributeIds) {
    int parentId = getParent(id);
    assert parentId >= 0 && parentId < recordCount;
    if (parentId > 0 && getParent(parentId) > 0) {
      int parentFlags = getFlags(parentId);
      assert (parentFlags & FREE_RECORD_FLAG) == 0 : parentId + ": "+Integer.toHexString(parentFlags);
      assert (parentFlags & PersistentFS.IS_DIRECTORY_FLAG) != 0 : parentId + ": "+Integer.toHexString(parentFlags);
    }

    String name = getName(id);
    LOG.assertTrue(parentId == 0 || !name.isEmpty(), "File with empty name found under " + getName(parentId) + ", id=" + id);

    checkContentsStorageSanity(id);
    checkAttributesStorageSanity(id, usedAttributeRecordIds, validAttributeIds);

    long length = getLength(id);
    assert length >= -1 : "Invalid file length found for " + name + ": " + length;
  }

  private static void checkContentsStorageSanity(int id) {
    int recordId = getContentRecordId(id);
    assert recordId >= 0;
    if (recordId > 0) {
      getContentStorage().checkSanity(recordId);
    }
  }

  private static void checkAttributesStorageSanity(int id, IntArrayList usedAttributeRecordIds, IntArrayList validAttributeIds) {
    int attributeRecordId = getAttributeRecordId(id);

    assert attributeRecordId >= 0;
    if (attributeRecordId > 0) {
      try {
        checkAttributesSanity(attributeRecordId, usedAttributeRecordIds, validAttributeIds);
      }
      catch (IOException ex) {
        throw DbConnection.handleError(ex);
      }
    }
  }

  private static void checkAttributesSanity(final int attributeRecordId, final IntArrayList usedAttributeRecordIds,
                                            final IntArrayList validAttributeIds) throws IOException {
    assert !usedAttributeRecordIds.contains(attributeRecordId);
    usedAttributeRecordIds.add(attributeRecordId);

    final DataInputStream dataInputStream = getAttributesStorage().readStream(attributeRecordId);
    try {
      while(dataInputStream.available() > 0) {
        int attId = DataInputOutputUtil.readINT(dataInputStream);
        int attDataRecordId = DataInputOutputUtil.readINT(dataInputStream);
        assert !usedAttributeRecordIds.contains(attDataRecordId);
        usedAttributeRecordIds.add(attDataRecordId);
        if (!validAttributeIds.contains(attId)) {
          assert !getNames().valueOf(attId).isEmpty();
          validAttributeIds.add(attId);
        }
        getAttributesStorage().checkSanity(attDataRecordId);
      }
    }
    finally {
      dataInputStream.close();
    }
  }

  public static RuntimeException handleError(Throwable e) {
    return DbConnection.handleError(e);
  }
}
