/*
 * Copyright (c) 2008, 2009, 2011-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.net4j.internal.db.ddl;

import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.ddl.IDBField;
import org.eclipse.net4j.db.ddl.IDBIndex;
import org.eclipse.net4j.db.ddl.IDBIndexField;
import org.eclipse.net4j.db.ddl.IDBSchema;
import org.eclipse.net4j.db.ddl.IDBSchemaElement;
import org.eclipse.net4j.db.ddl.IDBSchemaVisitor;
import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.db.ddl.SchemaElementNotFoundException;
import org.eclipse.net4j.spi.db.ddl.InternalDBField;
import org.eclipse.net4j.spi.db.ddl.InternalDBIndex;
import org.eclipse.net4j.spi.db.ddl.InternalDBSchema;
import org.eclipse.net4j.spi.db.ddl.InternalDBTable;
import org.eclipse.net4j.util.om.OMPlatform;

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * @author Eike Stepper
 */
public class DBIndex extends DBSchemaElement implements InternalDBIndex
{
  public static final ThreadLocal<Boolean> FIX_NULLABLE_INDEX_COLUMNS = new InheritableThreadLocal<Boolean>();

  public static final ThreadLocal<Set<IDBField>> NULLABLE_INDEX_FIELDS = new InheritableThreadLocal<Set<IDBField>>();

  private static final boolean DISABLE_NULLABLE_CHECK = Boolean
      .parseBoolean(OMPlatform.INSTANCE.getProperty("org.eclipse.net4j.db.DisableNullableCheck", "true"));

  private static final long serialVersionUID = 1L;

  private IDBTable table;

  private Type type;

  private List<IDBIndexField> indexFields = new ArrayList<IDBIndexField>();

  public DBIndex(IDBTable table, String name, Type type, IDBField[] fields)
  {
    super(name);
    this.table = table;
    this.type = type;

    for (int i = 0; i < fields.length; i++)
    {
      IDBField field = fields[i];
      addIndexField(field);
    }
  }

  /**
   * Constructor for deserialization.
   */
  protected DBIndex()
  {
  }

  @Override
  public IDBIndex getWrapper()
  {
    return (IDBIndex)super.getWrapper();
  }

  public SchemaElementType getSchemaElementType()
  {
    return SchemaElementType.INDEX;
  }

  public IDBSchema getSchema()
  {
    return table.getSchema();
  }

  public IDBTable getTable()
  {
    return table;
  }

  public IDBTable getParent()
  {
    return getTable();
  }

  public Type getType()
  {
    return type;
  }

  public void setType(Type type)
  {
    assertUnlocked();
    this.type = type;
  }

  @Deprecated
  public int getPosition()
  {
    IDBIndex[] indices = table.getIndices();
    return Arrays.asList(indices).indexOf(this);
  }

  public IDBIndexField addIndexField(IDBField field)
  {
    assertUnlocked();

    if (type != Type.NON_UNIQUE && !field.isNotNull())
    {
      if (!DISABLE_NULLABLE_CHECK && FIX_NULLABLE_INDEX_COLUMNS.get() != Boolean.TRUE)
      {
        Exception constructionStackTrace = ((InternalDBField)field).getConstructionStackTrace();
        throw new DBException(
            "Index field is nullable: " + field //$NON-NLS-1$
                + " (to disable this check run with '-Dorg.eclipse.net4j.db.DisableNullableCheck=true')",
            constructionStackTrace);
      }

      Set<IDBField> nullableIndexFields = NULLABLE_INDEX_FIELDS.get();
      if (nullableIndexFields == null)
      {
        nullableIndexFields = new HashSet<IDBField>();
        NULLABLE_INDEX_FIELDS.set(nullableIndexFields);
      }

      nullableIndexFields.add(field);
    }

    if (field.getTable() != table)
    {
      throw new DBException("Index field is from different table: " + field); //$NON-NLS-1$
    }

    String name = field.getName();
    if (getIndexField(name) != null)
    {
      throw new DBException("Index field exists: " + name); //$NON-NLS-1$
    }

    int position = indexFields.size();
    IDBIndexField indexField = new DBIndexField(this, field, position);
    indexFields.add(indexField);
    resetElements();
    return indexField;
  }

  public IDBIndexField addIndexField(String name) throws SchemaElementNotFoundException
  {
    IDBField field = table.getFieldSafe(name);
    return addIndexField(field);
  }

  public void removeIndexField(IDBIndexField indexFieldToRemove)
  {
    assertUnlocked();

    boolean found = false;
    for (Iterator<IDBIndexField> it = indexFields.iterator(); it.hasNext();)
    {
      IDBIndexField indexField = it.next();
      if (found)
      {
        ((InternalDBField)indexField).setPosition(indexField.getPosition() - 1);
      }
      else if (indexField == indexFieldToRemove)
      {
        it.remove();
        found = true;
      }
    }

    resetElements();
  }

  public IDBIndexField getIndexFieldSafe(String name) throws SchemaElementNotFoundException
  {
    IDBIndexField indexField = getIndexField(name);
    if (indexField == null)
    {
      throw new SchemaElementNotFoundException(this, SchemaElementType.INDEX_FIELD, name);
    }

    return indexField;
  }

  public IDBIndexField getIndexField(String name)
  {
    return findElement(getIndexFields(), name);
  }

  public IDBIndexField getIndexField(int position)
  {
    return indexFields.get(position);
  }

  public IDBField getFieldSafe(String name) throws SchemaElementNotFoundException
  {
    IDBIndexField indexField = getIndexFieldSafe(name);
    return indexField.getField();
  }

  public IDBField getField(String name)
  {
    name = name(name);
    for (IDBIndexField indexField : indexFields)
    {
      if (indexField.getName() == name)
      {
        return indexField.getField();
      }
    }

    return null;
  }

  public IDBField getField(int position)
  {
    return indexFields.get(position).getField();
  }

  public int getFieldCount()
  {
    return indexFields.size();
  }

  public IDBIndexField[] getIndexFields()
  {
    return indexFields.toArray(new IDBIndexField[indexFields.size()]);
  }

  public IDBField[] getFields()
  {
    IDBField[] fields = new IDBField[indexFields.size()];
    for (int i = 0; i < fields.length; i++)
    {
      fields[i] = getField(i);
    }

    return fields;
  }

  public String getFullName()
  {
    return getName();
  }

  public void remove()
  {
    ((InternalDBTable)table).removeIndex(this);
  }

  @Override
  protected void collectElements(List<IDBSchemaElement> elements)
  {
    elements.addAll(indexFields);
  }

  @Override
  protected void doAccept(IDBSchemaVisitor visitor)
  {
    visitor.visit(this);
  }

  @Override
  protected void dumpAdditionalProperties(Writer writer) throws IOException
  {
    writer.append(", type=");
    writer.append(String.valueOf(getType()));
  }

  private void assertUnlocked()
  {
    ((InternalDBSchema)table.getSchema()).assertUnlocked();
  }
}
