/*
 * Copyright (c) 2010-2012, 2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.emf.cdo.internal.workspace;

import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.server.IStoreAccessor;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.workspace.InternalCDOWorkspace;
import org.eclipse.emf.cdo.spi.workspace.InternalCDOWorkspaceBase;
import org.eclipse.emf.cdo.workspace.CDOWorkspaceBase;
import org.eclipse.emf.cdo.workspace.CDOWorkspaceUtil;

import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.factory.ProductCreationException;
import org.eclipse.net4j.util.io.ExtendedDataInputStream;
import org.eclipse.net4j.util.io.ExtendedDataOutputStream;
import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.net4j.util.om.monitor.Monitor;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

/**
 * @author Eike Stepper
 */
public class FolderCDOWorkspaceBase extends AbstractCDOWorkspaceBase
{
  private final File folder;

  private final File addedAndDetachedFile;

  public FolderCDOWorkspaceBase(File folder)
  {
    this.folder = folder.getAbsoluteFile();
    addedAndDetachedFile = new File(folder, "_addedAndDetached.log");
  }

  @Override
  public void init(InternalCDOWorkspace workspace)
  {
    super.init(workspace);
    createFolder();
  }

  public final File getFolder()
  {
    return folder;
  }

  public final synchronized InternalCDORevision getRevision(CDOID id)
  {
    File file = getFile(id);
    return readRevision(file);
  }

  public boolean isAddedObject(CDOID id)
  {
    File file = getFile(id);
    if (!file.exists())
    {
      return false;
    }

    return file.length() == 0;
  }

  public void deleteAddedAndDetachedObjects(IStoreAccessor.Raw accessor, CDOBranch branch)
  {
    if (!addedAndDetachedFile.exists())
    {
      return;
    }

    FileReader fileReader = null;

    try
    {
      fileReader = new FileReader(addedAndDetachedFile);

      @SuppressWarnings("resource")
      BufferedReader lineReader = new BufferedReader(fileReader);

      String line;
      while ((line = lineReader.readLine()) != null)
      {
        String[] tokens = line.split("\t");

        CDOID id = CDOIDUtil.read(tokens[0]);
        int detachedVersion = Integer.parseInt(tokens[1]);

        for (int v = 1; v <= detachedVersion; v++)
        {
          accessor.rawDelete(id, v, branch, null, new Monitor());
        }
      }
    }
    catch (IOException ex)
    {
      throw new IllegalStateException("Could not read from " + addedAndDetachedFile, ex);
    }
    finally
    {
      IOUtil.close(fileReader);
    }
  }

  @Override
  public String toString()
  {
    return "FolderBase[" + folder + "]";
  }

  @Override
  protected void doClear()
  {
    IOUtil.delete(folder);
    checkExists(folder, false);
    createFolder();
  }

  @Override
  protected Set<CDOID> doGetIDs()
  {
    return doGetIDs(folder);
  }

  @Override
  protected void doRegisterChangedOrDetachedObject(InternalCDORevision revision)
  {
    File file = getFile(revision.getID());
    if (file.exists())
    {
      return;
    }

    writeRevision(revision, file);
  }

  @Override
  protected void doRegisterAddedAndDetachedObject(InternalCDORevision revision)
  {
    CDOID id = revision.getID();
    int detachedVersion = revision.getVersion();

    String key = getKey(id);

    FileWriter writer = null;

    try
    {
      writer = new FileWriter(addedAndDetachedFile, true);
      writer.write(key);
      writer.write("\t");
      writer.write(Integer.toString(detachedVersion));
      writer.write("\n");
    }
    catch (IOException ex)
    {
      throw new IllegalStateException("Could not write to " + addedAndDetachedFile, ex);
    }
    finally
    {
      IOUtil.close(writer);
    }
  }

  @Override
  protected void doRegisterAddedObject(CDOID id)
  {
    File file = getFile(id);
    if (file.exists())
    {
      return;
    }

    FileOutputStream fos = null;

    try
    {
      fos = new FileOutputStream(file); // Just create an empty marker file
    }
    catch (IOException ex)
    {
      throw new IllegalStateException("Could not write to " + file, ex);
    }
    finally
    {
      IOUtil.close(fos);
    }
  }

  @Override
  protected void doDeregisterObject(CDOID id)
  {
    File file = getFile(id);
    file.delete();
    checkExists(file, false);
  }

  protected CDOID getCDOID(String filename)
  {
    return CDOIDUtil.read(filename);
  }

  protected String getKey(CDOID id)
  {
    StringBuilder builder = new StringBuilder();
    CDOIDUtil.write(builder, id);
    return builder.toString();
  }

  protected File getFile(CDOID id)
  {
    String key = getKey(id);
    return new File(folder, key);
  }

  private void createFolder()
  {
    IOUtil.mkdirs(folder);
    checkExists(folder, true);
  }

  private void checkExists(File file, boolean exists)
  {
    if (exists)
    {
      if (!file.exists())
      {
        throw new IllegalStateException("File does not exist: " + file);
      }
    }
    else
    {
      if (file.exists())
      {
        throw new IllegalStateException("File does still exist: " + file);
      }
    }
  }

  private void writeRevision(InternalCDORevision revision, File file)
  {
    FileOutputStream fos = null;

    try
    {
      fos = new FileOutputStream(file);
      ExtendedDataOutputStream edos = new ExtendedDataOutputStream(fos);
      CDODataOutput out = createCDODataOutput(edos);
      out.writeCDORevision(revision, CDORevision.UNCHUNKED);
      edos.flush();
    }
    catch (IOException ex)
    {
      throw new IllegalStateException("Could not write to " + file, ex);
    }
    finally
    {
      IOUtil.close(fos);
    }
  }

  private InternalCDORevision readRevision(File file)
  {
    if (!file.exists() || file.length() == 0)
    {
      return null;
    }

    FileInputStream fis = null;

    try
    {
      fis = new FileInputStream(file);
      ExtendedDataInputStream edis = new ExtendedDataInputStream(fis);
      CDODataInput in = createCDODataInput(edis);
      return (InternalCDORevision)in.readCDORevision();
    }
    catch (IOException ex)
    {
      throw new IllegalStateException("Could not read from " + file, ex);
    }
    finally
    {
      IOUtil.close(fis);
    }
  }

  private Set<CDOID> doGetIDs(File folder)
  {
    Set<CDOID> ids = new HashSet<CDOID>();

    if (folder.isDirectory())
    {
      File[] files = folder.listFiles();
      if (files != null)
      {
        for (File file : files)
        {
          if (!ObjectUtil.equals(file, addedAndDetachedFile))
          {
            CDOID id = getCDOID(file.getName());
            ids.add(id);
          }
        }
      }
    }

    return ids;
  }

  /**
   * @author Eike Stepper
   */
  public static final class Factory extends org.eclipse.net4j.util.factory.Factory
  {
    public static final String TYPE = "folder";

    public Factory()
    {
      super(InternalCDOWorkspaceBase.PRODUCT_GROUP, TYPE);
    }

    public Factory(String productGroup, String type)
    {
      super(productGroup, type);
    }

    public CDOWorkspaceBase create(String description) throws ProductCreationException
    {
      return CDOWorkspaceUtil.createFolderWorkspaceBase(new File(description));
    }
  }
}
