/*
 * Copyright 2000-2013 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.
 */
package com.intellij.openapi.externalSystem.model;

import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.*;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.*;

/**
 * This class provides a generic graph infrastructure with ability to store particular data. The main purpose is to 
 * allow easy extensible data domain construction.
 * <p/>
 * Example: we might want to describe project model like 'project' which has multiple 'module' children where every
 * 'module' has a collection of child 'content root' and dependencies nodes etc. When that is done, plugins can easily
 * enhance any project. For example, particular framework can add facet settings as one more 'project' node's child.
 * <p/>
 * Not thread-safe.
 *
 * @author Denis Zhdanov
 * @since 4/12/13 11:53 AM
 */
public class DataNode<T> implements Serializable {

  private static final long serialVersionUID = 1L;

  @NotNull private final List<DataNode<?>> myChildren = ContainerUtilRt.newArrayList();

  @NotNull private final Key<T> myKey;
  private transient T myData;
  private byte[] myRawData;

  @Nullable private final DataNode<?> myParent;

  public DataNode(@NotNull Key<T> key, @NotNull T data, @Nullable DataNode<?> parent) {
    myKey = key;
    myData = data;
    myParent = parent;
  }

  @Nullable
  public DataNode<?> getParent() {
    return myParent;
  }

  @NotNull
  public <T> DataNode<T> createChild(@NotNull Key<T> key, @NotNull T data) {
    DataNode<T> result = new DataNode<T>(key, data, this);
    myChildren.add(result);
    return result;
  }

  @NotNull
  public <T> DataNode<T> createOrReplaceChild(@NotNull Key<T> key, @NotNull T data) {
    for (Iterator<DataNode<?>> iterator = myChildren.iterator(); iterator.hasNext(); ) {
      DataNode<?> child = iterator.next();
      if (child.getKey().equals(key)) {
        iterator.remove();
        break;
      }
    }
    return createChild(key, data);
  }

  @NotNull
  public Key<T> getKey() {
    return myKey;
  }

  @NotNull
  public T getData() {
    if (myData == null) {
      prepareData(getClass().getClassLoader(), Thread.currentThread().getContextClassLoader());
    }
    return myData;
  }

  /**
   * This class is a generic holder for any kind of project data. That project data might originate from different locations, e.g.
   * core ide plugins, non-core ide plugins, third-party plugins etc. That means that when a service from a core plugin needs to
   * unmarshall {@link DataNode} object, its content should not be unmarshalled as well because its class might be unavailable here.
   * <p/>
   * That's why the content is delivered as a raw byte array and this method allows to build actual java object from it using
   * the right class loader.
   * <p/>
   * This method is a no-op if the content is already built.
   *  
   * @param loaders  class loaders which are assumed to be able to build object of the target content class
   */
  @SuppressWarnings({"unchecked", "IOResourceOpenedButNotSafelyClosed"})
  public void prepareData(@NotNull final ClassLoader ... loaders) {
    if (myData != null) {
      return;
    }
    ObjectInputStream oIn = null;
    try {
      oIn = new ObjectInputStream(new ByteArrayInputStream(myRawData)) {
        @Override
        protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
          String name = desc.getName();
          for (ClassLoader loader : loaders) {
            try {
              return Class.forName(name, false, loader);
            }
            catch (ClassNotFoundException e) {
              // Ignore
            }
          }
          return super.resolveClass(desc);
        }

        @Override
        protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
          for (ClassLoader loader : loaders) {
            try {
              return doResolveProxyClass(interfaces, loader);
            }
            catch (ClassNotFoundException e) {
              // Ignore
            }
          }
          return super.resolveProxyClass(interfaces);
        }
        
        private Class<?> doResolveProxyClass(@NotNull String[] interfaces, @NotNull ClassLoader loader) throws ClassNotFoundException {
          ClassLoader nonPublicLoader = null;
          boolean hasNonPublicInterface = false;

          // define proxy in class loader of non-public interface(s), if any
          Class[] classObjs = new Class[interfaces.length];
          for (int i = 0; i < interfaces.length; i++) {
            Class cl = Class.forName(interfaces[i], false, loader);
            if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
              if (hasNonPublicInterface) {
                if (nonPublicLoader != cl.getClassLoader()) {
                  throw new IllegalAccessError(
                    "conflicting non-public interface class loaders");
                }
              } else {
                nonPublicLoader = cl.getClassLoader();
                hasNonPublicInterface = true;
              }
            }
            classObjs[i] = cl;
          }
          try {
            return Proxy.getProxyClass(hasNonPublicInterface ? nonPublicLoader : loader, classObjs);
          }
          catch (IllegalArgumentException e) {
            throw new ClassNotFoundException(null, e);
          }
        }
      };
      myData = (T)oIn.readObject();
      myRawData = null;
    }
    catch (IOException e) {
      throw new IllegalStateException(
        String.format("Can't deserialize target data of key '%s'. Given class loaders: %s", myKey, Arrays.toString(loaders)),
        e
      );
    }
    catch (ClassNotFoundException e) {
      throw new IllegalStateException(
        String.format("Can't deserialize target data of key '%s'. Given class loaders: %s", myKey, Arrays.toString(loaders)),
        e
      );
    }
    finally {
      StreamUtil.closeStream(oIn);
    }
  }

  /**
   * Allows to retrieve data stored for the given key at the current node or any of its parents.
   *
   * @param key  target data's key
   * @param <T>  target data type
   * @return data stored for the current key and available via the current node (if any)
   */
  @SuppressWarnings("unchecked")
  @Nullable
  public <T> T getData(@NotNull Key<T> key) {
    if (myKey.equals(key)) {
      return (T)myData;
    }
    for (DataNode<?> p = myParent; p != null; p = p.myParent) {
      if (p.myKey.equals(key)) {
        return (T)p.myData;
      }
    }
    return null;
  }

  @SuppressWarnings("unchecked")
  @Nullable
  public <T> DataNode<T> getDataNode(@NotNull Key<T> key) {
    if (myKey.equals(key)) {
      return (DataNode<T>)this;
    }
    for (DataNode<?> p = myParent; p != null; p = p.myParent) {
      if (p.myKey.equals(key)) {
        return (DataNode<T>)p;
      }
    }
    return null;
  }

  public void addChild(@NotNull DataNode<?> child) {
    myChildren.add(child);
  }

  @NotNull
  public Collection<DataNode<?>> getChildren() {
    return myChildren;
  }

  private void writeObject(ObjectOutputStream out) throws IOException {
    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    ObjectOutputStream oOut = new ObjectOutputStream(bOut);
    try {
      oOut.writeObject(myData);
    }
    finally {
      oOut.close();
    }
    myRawData = bOut.toByteArray();
    out.defaultWriteObject();
  }
  
  @Override
  public int hashCode() {
    int result = myChildren.hashCode();
    result = 31 * result + myKey.hashCode();
    result = 31 * result + getData().hashCode();
    return result;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    DataNode node = (DataNode)o;

    if (!myChildren.equals(node.myChildren)) return false;
    if (!getData().equals(node.getData())) return false;
    if (!myKey.equals(node.myKey)) return false;

    return true;
  }

  @Override
  public String toString() {
    return String.format("%s: %s", myKey, getData());
  }
}
