/*
 * Copyright (c) 2010-2012, 2014 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.server;

import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
import org.eclipse.emf.cdo.common.lob.CDOLobUtil;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
import org.eclipse.emf.cdo.common.model.CDOPackageUnit.Type;
import org.eclipse.emf.cdo.common.model.EMFUtil;
import org.eclipse.emf.cdo.common.model.EMFUtil.ExtResourceSet;
import org.eclipse.emf.cdo.common.revision.CDOList;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranch;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry.PackageLoader;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.server.InternalRepository;

import org.eclipse.net4j.util.HexUtil;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.io.AsyncOutputStream;
import org.eclipse.net4j.util.io.AsyncWriter;
import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.monitor.Monitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Imports the complete contents of a {@link IRepository repository} from the output created by a
 * {@link CDOServerExporter exporter} into a new repository.
 * <p>
 * Subtypes specifiy the actual exchange format.
 *
 * @author Eike Stepper
 * @since 4.0
 * @apiviz.has {@link CDOServerImporter.Handler}
 */
public abstract class CDOServerImporter
{
  private InternalRepository repository;

  public CDOServerImporter(IRepository repository)
  {
    this.repository = (InternalRepository)repository;
    init();
  }

  private void init()
  {
    LifecycleUtil.checkInactive(repository);
    repository.setSkipInitialization(true);
    repository.getStore().setDropAllDataOnActivate(true);
    LifecycleUtil.activate(repository);
  }

  protected final InternalRepository getRepository()
  {
    return repository;
  }

  public void importRepository(InputStream in) throws Exception
  {
    try
    {
      FlushHandler handler = new FlushHandler();
      importAll(in, handler);
      handler.flush();
    }
    finally
    {
      StoreThreadLocal.release();
      repository = null;
    }
  }

  protected abstract void importAll(InputStream in, Handler handler) throws Exception;

  /**
   * Persists the data that has been read by a {@link CDOServerImporter importer} into a new {@link IRepository
   * repository}.
   *
   * @author Eike Stepper
   */
  public static interface Handler extends CDORevisionHandler, CDOLobHandler
  {
    public void handleRepository(String name, String uuid, CDOID root, long created, long committed);

    public InternalCDOPackageUnit handlePackageUnit(String id, Type type, long time, String data);

    public InternalCDOPackageInfo handlePackageInfo(String packageURI);

    public InternalCDOPackageRegistry handleModels();

    public InternalCDOBranch handleBranch(int id, String name, long time, int parentID);

    public void handleCommitInfo(long time, long previous, int branch, String user, String comment);

    public void flush();
  }

  /**
   * @author Eike Stepper
   */
  private final class FlushHandler implements Handler
  {
    private OMMonitor monitor = new Monitor();

    private IStoreAccessor.Raw accessor;

    private Map<String, String> models = new HashMap<String, String>();

    private LinkedList<InternalCDOPackageUnit> packageUnits = new LinkedList<InternalCDOPackageUnit>();

    private List<InternalCDOPackageInfo> packageInfos;

    private InternalCDOPackageRegistry packageRegistry = getRepository().getPackageRegistry(false);

    public FlushHandler()
    {
    }

    public void handleRepository(String name, String uuid, CDOID root, long created, long committed)
    {
      repository.getStore().setCreationTime(created);
      repository.getStore().setLastCommitTime(committed);

      InternalCDOBranchManager branchManager = repository.getBranchManager();
      repository.initMainBranch(branchManager, created);
      LifecycleUtil.activate(branchManager);

      repository.initSystemPackages(true);
      repository.setRootResourceID(root);

      // InternalSession session = repository.getSessionManager().openSession(null);
      // StoreThreadLocal.setSession(session);

      accessor = (IStoreAccessor.Raw)repository.getStore().getWriter(null);
      StoreThreadLocal.setAccessor(accessor);
    }

    public InternalCDOPackageUnit handlePackageUnit(String id, Type type, long time, String data)
    {
      collectPackageInfos();

      InternalCDOPackageUnit packageUnit = packageRegistry.createPackageUnit();
      packageUnit.setOriginalType(type);
      packageUnit.setTimeStamp(time);

      models.put(id, data);
      packageUnits.add(packageUnit);
      packageInfos = new ArrayList<InternalCDOPackageInfo>();
      return packageUnit;
    }

    public InternalCDOPackageInfo handlePackageInfo(String packageURI)
    {
      InternalCDOPackageInfo packageInfo = (InternalCDOPackageInfo)CDOModelUtil.createPackageInfo();
      packageInfo.setPackageURI(packageURI);
      packageInfos.add(packageInfo);
      return packageInfo;
    }

    public InternalCDOPackageRegistry handleModels()
    {
      collectPackageInfos();
      InternalCDOPackageUnit[] array = packageUnits.toArray(new InternalCDOPackageUnit[packageUnits.size()]);
      packageUnits = null;

      final ExtResourceSet resourceSet = EMFUtil.createExtResourceSet(packageRegistry, false, false);

      PackageLoader loader = new PackageLoader()
      {
        public EPackage[] loadPackages(CDOPackageUnit packageUnit)
        {
          String id = packageUnit.getID();
          String data = models.get(id);

          EPackage ePackage = EMFUtil.createEPackage(id, data.getBytes(), false, resourceSet, true);
          return EMFUtil.getAllPackages(ePackage);
        }
      };

      packageRegistry.putPackageUnits(array, CDOPackageUnit.State.PROXY);
      for (InternalCDOPackageUnit packageUnit : array)
      {
        packageUnit.load(loader, false);
      }

      // Before we resolve, we configure the resourceSet to start delegating, which means
      // it will consult the packageRegistry for packages it didn't just load -- such as the Ecore
      // package
      resourceSet.setDelegating(true);
      EMFUtil.safeResolveAll(resourceSet);

      accessor.rawStore(array, monitor);

      return packageRegistry;
    }

    public InternalCDOBranch handleBranch(int id, String name, long time, int parentID)
    {
      InternalCDOBranchManager branchManager = repository.getBranchManager();
      if (id == CDOBranch.MAIN_BRANCH_ID)
      {
        return branchManager.getMainBranch();
      }

      InternalCDOBranch parent = branchManager.getBranch(parentID);
      return branchManager.createBranch(id, name, parent, time);
    }

    public boolean handleRevision(CDORevision revision)
    {
      accessor.rawStore((InternalCDORevision)revision, monitor);
      return true;
    }

    public OutputStream handleBlob(final byte[] id, final long size) throws IOException
    {
      return new AsyncOutputStream()
      {
        @Override
        protected void asyncWrite(InputStream in) throws IOException
        {
          accessor.rawStore(id, size, in);
        }
      };
    }

    public Writer handleClob(final byte[] id, final long size) throws IOException
    {
      return new AsyncWriter()
      {
        @Override
        protected void asyncWrite(Reader in) throws IOException
        {
          accessor.rawStore(id, size, in);
        }
      };
    }

    public void handleCommitInfo(long time, long previous, int branchID, String user, String comment)
    {
      CDOBranch branch = repository.getBranchManager().getBranch(branchID);
      accessor.rawStore(branch, time, previous, user, comment, monitor);
    }

    public void flush()
    {
      accessor.rawCommit(1.0, monitor);
    }

    private void collectPackageInfos()
    {
      if (packageInfos != null)
      {
        InternalCDOPackageUnit packageUnit = packageUnits.getLast();
        packageUnit.setPackageInfos(packageInfos.toArray(new InternalCDOPackageInfo[packageInfos.size()]));
        packageInfos = null;
      }
    }
  }

  /**
   * An {@link CDOServerImporter importer} that reads and interprets XML output created by an
   * {@link CDOServerExporter.XML XML exporter}.
   *
   * @author Eike Stepper
   */
  public static class XML extends CDOServerImporter implements CDOServerExporter.XMLConstants
  {
    public XML(IRepository repository)
    {
      super(repository);
    }

    @Override
    protected void importAll(InputStream in, final Handler handler) throws Exception
    {
      DefaultHandler xmlHandler = new XMLHandler(handler);

      SAXParserFactory factory = SAXParserFactory.newInstance();
      SAXParser saxParser = factory.newSAXParser();
      saxParser.parse(in, xmlHandler);
    }

    /**
     * @author Eike Stepper
     */
    private static final class XMLHandler extends DefaultHandler
    {
      private Handler handler;

      private InternalCDOPackageRegistry packageRegistry;

      private InternalCDOBranch branch;

      private InternalCDORevision revision;

      private Character blobChar;

      private OutputStream blob;

      private Writer clob;

      private XMLHandler(Handler handler)
      {
        this.handler = handler;
      }

      @Override
      public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
      {
        if (REPOSITORY.equals(qName))
        {
          String name = attributes.getValue(REPOSITORY_NAME);
          String uuid = attributes.getValue(REPOSITORY_UUID);
          CDOID root = id(attributes.getValue(REPOSITORY_ROOT));
          long created = Long.parseLong(attributes.getValue(REPOSITORY_CREATED));
          long committed = Long.parseLong(attributes.getValue(REPOSITORY_COMMITTED));
          handler.handleRepository(name, uuid, root, created, committed);
        }
        else if (PACKAGE_UNIT.equals(qName))
        {
          String id = attributes.getValue(PACKAGE_UNIT_ID);
          Type type = CDOPackageUnit.Type.valueOf(attributes.getValue(PACKAGE_UNIT_TYPE));
          long time = Long.parseLong(attributes.getValue(PACKAGE_UNIT_TIME));
          String data = attributes.getValue(PACKAGE_UNIT_DATA);
          handler.handlePackageUnit(id, type, time, data);
        }
        else if (PACKAGE_INFO.equals(qName))
        {
          String packageURI = attributes.getValue(PACKAGE_INFO_URI);
          handler.handlePackageInfo(packageURI);
        }
        else if (BRANCH.equals(qName))
        {
          int id = Integer.parseInt(attributes.getValue(BRANCH_ID));
          String name = attributes.getValue(BRANCH_NAME);
          long time = Long.parseLong(attributes.getValue(BRANCH_TIME));
          String parent = attributes.getValue(BRANCH_PARENT);
          int parentID = parent == null ? 0 : Integer.parseInt(parent);
          branch = handler.handleBranch(id, name, time, parentID);
        }
        else if (REVISION.equals(qName))
        {
          CDOClassifierRef classifierRef = new CDOClassifierRef(attributes.getValue(REVISION_CLASS));
          EClass eClass = (EClass)classifierRef.resolve(packageRegistry);
          revision = (InternalCDORevision)CDORevisionFactory.DEFAULT.createRevision(eClass);
          revision.setID(id(attributes.getValue(REVISION_ID)));
          revision.setBranchPoint(branch.getPoint(Long.parseLong(attributes.getValue(REVISION_TIME))));
          revision.setVersion(Integer.parseInt(attributes.getValue(REVISION_VERSION)));
          String revised = attributes.getValue(REVISION_REVISED);
          if (revised != null)
          {
            revision.setRevised(Long.parseLong(revised));
          }

          String resourceID = attributes.getValue(REVISION_RESOURCE);
          if (resourceID != null)
          {
            revision.setResourceID(id(resourceID));
          }

          String containerID = attributes.getValue(REVISION_CONTAINER);
          if (containerID != null)
          {
            revision.setContainerID(id(containerID));
          }

          String featureID = attributes.getValue(REVISION_FEATURE);
          if (featureID != null)
          {
            revision.setContainingFeatureID(Integer.parseInt(featureID));
          }
        }
        else if (FEATURE.equals(qName))
        {
          String name = attributes.getValue(FEATURE_NAME);
          Object value = value(attributes);

          EClass eClass = revision.getEClass();
          EStructuralFeature feature = eClass.getEStructuralFeature(name);
          if (feature == null)
          {
            throw new IllegalStateException("Feature " + name + " not found in class " + eClass.getName());
          }

          if (feature.isMany())
          {
            CDOList list = revision.getList(feature);
            list.add(value);
          }
          else
          {
            if (value != null)
            {
              revision.setValue(feature, value);
            }
          }
        }
        else if (BLOB.equals(qName))
        {
          try
          {
            byte[] id = HexUtil.hexToBytes(attributes.getValue(LOB_ID));
            long size = Long.parseLong(attributes.getValue(LOB_SIZE));
            blob = handler.handleBlob(id, size);
          }
          catch (IOException ex)
          {
            throw WrappedException.wrap(ex);
          }
        }
        else if (CLOB.equals(qName))
        {
          try
          {
            byte[] id = HexUtil.hexToBytes(attributes.getValue(LOB_ID));
            long size = Long.parseLong(attributes.getValue(LOB_SIZE));
            clob = handler.handleClob(id, size);
          }
          catch (IOException ex)
          {
            throw WrappedException.wrap(ex);
          }
        }
        else if (COMMIT.equals(qName))
        {
          long time = Long.parseLong(attributes.getValue(COMMIT_TIME));

          String value = attributes.getValue(COMMIT_PREVIOUS);
          long previous = value == null ? CDOBranchPoint.UNSPECIFIED_DATE : Long.parseLong(value);

          value = attributes.getValue(COMMIT_BRANCH);
          int branch = value == null ? CDOBranch.MAIN_BRANCH_ID : Integer.parseInt(value);

          String user = attributes.getValue(COMMIT_USER);
          String comment = attributes.getValue(COMMIT_COMMENT);

          handler.handleCommitInfo(time, previous, branch, user, comment);
        }
      }

      @Override
      public void characters(char[] ch, int start, int length) throws SAXException
      {
        if (blob != null)
        {
          try
          {
            if (blobChar != null)
            {
              char[] firstChars = { blobChar, ch[start] };
              blobChar = null;

              byte[] firstByte = HexUtil.hexToBytes(new String(firstChars));
              blob.write(firstByte, 0, 1);

              ++start;
              --length;
            }

            if ((length & 1) == 1) // odd length?
            {
              --length;
              blobChar = ch[length];
            }

            if (start != 0 || length != ch.length)
            {
              char[] tmp = new char[length];
              System.arraycopy(ch, start, tmp, 0, length);
              ch = tmp;
            }

            byte[] buf = HexUtil.hexToBytes(new String(ch));
            blob.write(buf);
          }
          catch (IOException ex)
          {
            throw WrappedException.wrap(ex);
          }
        }
        else if (clob != null)
        {
          try
          {
            clob.write(ch, start, length);
          }
          catch (IOException ex)
          {
            throw WrappedException.wrap(ex);
          }
        }
      }

      @Override
      public void endElement(String uri, String localName, String qName) throws SAXException
      {
        if (MODELS.equals(qName))
        {
          packageRegistry = handler.handleModels();
        }
        else if (BRANCH.equals(qName))
        {
          branch = null;
        }
        else if (REVISION.equals(qName))
        {
          handler.handleRevision(revision);
          revision = null;
        }
        else if (BLOB.equals(qName))
        {
          IOUtil.close(blob);
          blob = null;
        }
        else if (CLOB.equals(qName))
        {
          IOUtil.close(clob);
          clob = null;
        }
      }

      protected final CDOID id(String str)
      {
        return CDOIDUtil.read(str);
      }

      protected Object value(Attributes attributes)
      {
        String type = attributes.getValue(FEATURE_TYPE);

        if (TYPE_BLOB.equals(type))
        {
          byte[] id = HexUtil.hexToBytes(attributes.getValue(FEATURE_ID));
          long size = Long.parseLong(attributes.getValue(FEATURE_SIZE));
          return CDOLobUtil.createBlob(id, size);
        }

        if (TYPE_CLOB.equals(type))
        {
          byte[] id = HexUtil.hexToBytes(attributes.getValue(FEATURE_ID));
          long size = Long.parseLong(attributes.getValue(FEATURE_SIZE));
          return CDOLobUtil.createClob(id, size);
        }

        if (TYPE_FEATURE_MAP.equals(type))
        {
          String innerFeatureName = attributes.getValue(FEATURE_INNER_FEATURE);
          EStructuralFeature innerFeature = revision.getEClass().getEStructuralFeature(innerFeatureName);

          String innerType = attributes.getValue(FEATURE_INNER_TYPE);
          Object innerValue = value(attributes, innerType);

          return CDORevisionUtil.createFeatureMapEntry(innerFeature, innerValue);
        }

        return value(attributes, type);
      }

      protected Object value(Attributes attributes, String type)
      {
        String str = attributes.getValue(FEATURE_VALUE);
        if (str == null)
        {
          return null;
        }

        if (type == null || String.class.getSimpleName().equals(type))
        {
          return str;
        }

        if (Object.class.getSimpleName().equals(type))
        {
          return id(str);
        }

        if (Boolean.class.getSimpleName().equals(type))
        {
          return Boolean.valueOf(str);
        }

        if (Character.class.getSimpleName().equals(type))
        {
          return str.charAt(0);
        }

        if (Byte.class.getSimpleName().equals(type))
        {
          return Byte.valueOf(str);
        }

        if (Short.class.getSimpleName().equals(type))
        {
          return Short.valueOf(str);
        }

        if (Integer.class.getSimpleName().equals(type))
        {
          return Integer.valueOf(str);
        }

        if (Long.class.getSimpleName().equals(type))
        {
          return Long.valueOf(str);
        }

        if (Float.class.getSimpleName().equals(type))
        {
          return Float.valueOf(str);
        }

        if (Double.class.getSimpleName().equals(type))
        {
          return Double.valueOf(str);
        }

        if (Date.class.getSimpleName().equals(type))
        {
          return new Date(Long.valueOf(str));
        }

        if (BigDecimal.class.getSimpleName().equals(type))
        {
          return new BigDecimal(str);
        }

        if (BigInteger.class.getSimpleName().equals(type))
        {
          return new BigInteger(str);
        }

        throw new IllegalArgumentException("Invalid type: " + type);
      }
    }
  }
}
