/*
 * Copyright (c) 2009-2013, 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.common.model;

import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.model.CDOPackageTypeRegistry;
import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
import org.eclipse.emf.cdo.common.model.EMFUtil;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
import org.eclipse.emf.cdo.common.util.CDOCommonUtil;
import org.eclipse.emf.cdo.internal.common.bundle.OM;
import org.eclipse.emf.cdo.internal.common.messages.Messages;
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.net4j.util.CheckUtil;
import org.eclipse.net4j.util.om.trace.ContextTracer;

import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Eike Stepper
 */
public class CDOPackageUnitImpl implements InternalCDOPackageUnit
{
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, CDOPackageUnitImpl.class);

  private InternalCDOPackageRegistry packageRegistry;

  private State state = State.PROXY;

  private Type type;

  private Type originalType;

  private long timeStamp;

  private InternalCDOPackageInfo[] packageInfos;

  public CDOPackageUnitImpl()
  {
  }

  public InternalCDOPackageRegistry getPackageRegistry()
  {
    return packageRegistry;
  }

  public void setPackageRegistry(InternalCDOPackageRegistry packageRegistry)
  {
    this.packageRegistry = packageRegistry;
  }

  public String getID()
  {
    try
    {
      return getTopLevelPackageInfo().getPackageURI();
    }
    catch (RuntimeException ex)
    {
      return Messages.getString("CDOPackageUnitImpl.0"); //$NON-NLS-1$
    }
  }

  public State getState()
  {
    return state;
  }

  public void setState(State state)
  {
    this.state = state;
    if (state == State.LOADED)
    {
      type = null;
    }
  }

  public Type getType()
  {
    if (getOriginalType() == Type.DYNAMIC)
    {
      type = Type.DYNAMIC;
    }
    else if (type == null || type == Type.UNKNOWN)
    {
      if (state == State.PROXY)
      {
        type = CDOPackageTypeRegistry.INSTANCE.lookup(getID());
      }
      else
      {
        InternalCDOPackageInfo packageInfo = getTopLevelPackageInfo();
        EPackage ePackage = packageInfo.getEPackage();
        type = CDOPackageTypeRegistry.INSTANCE.lookup(ePackage);
      }

      if (type == null)
      {
        type = Type.UNKNOWN;
      }
    }

    return type;
  }

  public Type getOriginalType()
  {
    return originalType;
  }

  public void setOriginalType(Type originalType)
  {
    this.originalType = originalType;
  }

  public long getTimeStamp()
  {
    return timeStamp;
  }

  public void setTimeStamp(long timeStamp)
  {
    this.timeStamp = timeStamp;
  }

  public InternalCDOPackageInfo getTopLevelPackageInfo()
  {
    if (packageInfos == null || packageInfos.length == 0)
    {
      throw new IllegalStateException(Messages.getString("CDOPackageUnitImpl.1")); //$NON-NLS-1$
    }

    return packageInfos[0];
  }

  public InternalCDOPackageInfo getPackageInfo(String packageURI)
  {
    for (InternalCDOPackageInfo packageInfo : packageInfos)
    {
      if (packageInfo.getPackageURI().equals(packageURI))
      {
        return packageInfo;
      }
    }

    return null;
  }

  public InternalCDOPackageInfo[] getPackageInfos()
  {
    return packageInfos;
  }

  public void setPackageInfos(InternalCDOPackageInfo[] packageInfos)
  {
    this.packageInfos = packageInfos;
    for (InternalCDOPackageInfo packageInfo : packageInfos)
    {
      packageInfo.setPackageUnit(this);
    }
  }

  public EPackage[] getEPackages(boolean loadOnDemand)
  {
    List<EPackage> result = new ArrayList<EPackage>();
    for (InternalCDOPackageInfo packageInfo : packageInfos)
    {
      EPackage ePackage = packageInfo.getEPackage(loadOnDemand);
      if (ePackage != null)
      {
        result.add(ePackage);
      }
    }

    return result.toArray(new EPackage[result.size()]);
  }

  public boolean isSystem()
  {
    return getTopLevelPackageInfo().isSystemPackage();
  }

  public boolean isResource()
  {
    return getTopLevelPackageInfo().isResourcePackage();
  }

  public void init(EPackage ePackage)
  {
    EPackage topLevelPackage = EMFUtil.getTopLevelPackage(ePackage);
    List<InternalCDOPackageInfo> result = new ArrayList<InternalCDOPackageInfo>();
    initPackageInfos(topLevelPackage, result);
    packageInfos = result.toArray(new InternalCDOPackageInfo[result.size()]);

    setState(State.NEW);
    setOriginalType(getType());
  }

  public void dispose()
  {
    packageInfos = null;
    setState(State.DISPOSED);
  }

  public synchronized void load(boolean resolve)
  {
    PackageLoader packageLoader = packageRegistry.getPackageLoader();
    load(packageLoader, resolve);
  }

  public synchronized void load(PackageLoader packageLoader, boolean resolve)
  {
    if (state == State.PROXY)
    {
      EPackage[] ePackages = null;
      ePackages = loadPackagesFromGlobalRegistry();
      if (ePackages == null)
      {
        ePackages = packageLoader.loadPackages(this);
      }

      for (EPackage ePackage : ePackages)
      {
        String packageURI = ePackage.getNsURI();
        InternalCDOPackageInfo packageInfo = getPackageInfo(packageURI);
        packageRegistry.registerPackageInfo(ePackage, packageInfo);
        if (resolve)
        {
          synchronized (ePackage)
          {
            EcoreUtil.resolveAll(ePackage);
          }
        }
      }

      setState(State.LOADED);
    }
  }

  public void write(CDODataOutput out, boolean withPackages) throws IOException
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("Writing {0}", this); //$NON-NLS-1$
    }

    out.writeBoolean(withPackages);
    if (withPackages)
    {
      CDOModelUtil.writePackage(out, packageInfos[0].getEPackage(), true, packageRegistry);
    }

    out.writeCDOPackageUnitType(originalType);
    out.writeLong(timeStamp);
    out.writeInt(packageInfos.length);
    for (InternalCDOPackageInfo packageInfo : packageInfos)
    {
      out.writeCDOPackageInfo(packageInfo);
    }
  }

  public void read(CDODataInput in, ResourceSet resourceSet) throws IOException
  {
    if (packageRegistry == null)
    {
      packageRegistry = (InternalCDOPackageRegistry)in.getPackageRegistry();
      if (packageRegistry == null)
      {
        EPackage.Registry resourceSetPackageRegistry = resourceSet.getPackageRegistry();
        if (resourceSetPackageRegistry instanceof InternalCDOPackageRegistry)
        {
          packageRegistry = (InternalCDOPackageRegistry)resourceSetPackageRegistry;
        }
      }
    }

    EPackage ePackage = null;
    boolean withPackages = in.readBoolean();
    if (withPackages)
    {
      CheckUtil.checkArg(resourceSet, "resourceSet"); //$NON-NLS-1$
      ePackage = CDOModelUtil.readPackage(in, resourceSet, true);
      EPackage globalPackage = loadPackageFromGlobalRegistry(ePackage.getNsURI());
      if (globalPackage != null)
      {
        ePackage = globalPackage;
      }

      setState(State.LOADED);
    }

    originalType = in.readCDOPackageUnitType();
    timeStamp = in.readLong();
    packageInfos = new InternalCDOPackageInfo[in.readInt()];
    for (int i = 0; i < packageInfos.length; i++)
    {
      packageInfos[i] = (InternalCDOPackageInfo)in.readCDOPackageInfo();
      packageInfos[i].setPackageUnit(this);
    }

    if (ePackage != null)
    {
      attachPackageInfos(ePackage);
    }

    if (TRACER.isEnabled())
    {
      TRACER.format("Read {0}", this); //$NON-NLS-1$
    }
  }

  public InternalCDOPackageUnit copy()
  {
    InternalCDOPackageUnit packageUnit = (InternalCDOPackageUnit)CDOModelUtil.createPackageUnit();

    InternalCDOPackageInfo[] thesePackageInfos = getPackageInfos();
    InternalCDOPackageInfo[] packageInfos = new InternalCDOPackageInfo[thesePackageInfos.length];
    for (int i = 0; i < thesePackageInfos.length; i++)
    {
      packageInfos[i] = thesePackageInfos[i].copy();
      packageInfos[i].setPackageUnit(packageUnit);
    }

    packageUnit.setPackageInfos(packageInfos);
    packageUnit.setOriginalType(getOriginalType());
    packageUnit.setState(getState());
    packageUnit.setTimeStamp(getTimeStamp());
    return packageUnit;
  }

  public int compareTo(CDOPackageUnit o)
  {
    return getID().compareTo(o.getID());
  }

  @Override
  public String toString()
  {
    String fmt = "CDOPackageUnit[id={0}, state={1}, type={2}, originalType={3}, timeStamp={4}]"; //$NON-NLS-1$
    return MessageFormat.format(fmt, getID(), getState(), getType(), getOriginalType(),
        CDOCommonUtil.formatTimeStamp(getTimeStamp()));
  }

  private void initPackageInfos(EPackage ePackage, List<InternalCDOPackageInfo> result)
  {
    InternalCDOPackageInfo packageInfo = (InternalCDOPackageInfo)CDOModelUtil.createPackageInfo();
    packageInfo.setPackageUnit(this);
    packageInfo.setPackageURI(ePackage.getNsURI());
    packageInfo.setParentURI(ePackage.getESuperPackage() == null ? null : ePackage.getESuperPackage().getNsURI());

    packageRegistry.basicPut(ePackage.getNsURI(), ePackage);
    packageRegistry.registerPackageInfo(ePackage, packageInfo);

    result.add(packageInfo);
    for (EPackage subPackage : ePackage.getESubpackages())
    {
      initPackageInfos(subPackage, result);
    }
  }

  private void attachPackageInfos(EPackage ePackage)
  {
    InternalCDOPackageInfo packageInfo = getPackageInfo(ePackage.getNsURI());
    if (packageInfo != null)
    {
      packageRegistry.registerPackageInfo(ePackage, packageInfo);
    }

    for (EPackage subPackage : ePackage.getESubpackages())
    {
      attachPackageInfos(subPackage);
    }
  }

  private EPackage[] loadPackagesFromGlobalRegistry()
  {
    EPackage[] ePackages = new EPackage[packageInfos.length];
    for (int i = 0; i < ePackages.length; i++)
    {
      ePackages[i] = loadPackageFromGlobalRegistry(packageInfos[i].getPackageURI());
      if (ePackages[i] == null)
      {
        return null;
      }
    }

    return ePackages;
  }

  private EPackage loadPackageFromGlobalRegistry(String packageURI)
  {
    return EPackage.Registry.INSTANCE.getEPackage(packageURI);
  }
}
