/*
 * Copyright 2000-2014 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 org.jetbrains.jps.builders.java.dependencyView;

import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.DataInputOutputUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.storage.BuildDataCorruptedException;
import org.jetbrains.org.objectweb.asm.Type;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;

/**
 * @author: db
 * Date: 14.02.11
 */
class TypeRepr {
  private static final byte PRIMITIVE_TYPE = 0x0;
  private static final byte CLASS_TYPE = 0x1;
  private static final byte ARRAY_TYPE = 0x2;

  private TypeRepr() {

  }

  interface AbstractType extends RW.Savable {
    AbstractType[] EMPTY_TYPE_ARRAY = new AbstractType[0];

    void updateClassUsages(DependencyContext context, int owner, Set<UsageRepr.Usage> s);
    String getDescr(DependencyContext context);
    void save(DataOutput out);
  }

  public static class PrimitiveType implements AbstractType {
    public final int type;

    @Override
    public String getDescr(final DependencyContext context) {
      return context.getValue(type);
    }

    @Override
    public void updateClassUsages(final DependencyContext context, final int owner, final Set<UsageRepr.Usage> s) {

    }

    @Override
    public void save(final DataOutput out) {
      try {
        out.writeByte(PRIMITIVE_TYPE);
        DataInputOutputUtil.writeINT(out, type);
      }
      catch (IOException e) {
        throw new BuildDataCorruptedException(e);
      }
    }

    PrimitiveType(final int type) {
      this.type = type;
    }

    PrimitiveType(final DataInput in) {
      try {
        type = DataInputOutputUtil.readINT(in);
      }
      catch (IOException e) {
        throw new BuildDataCorruptedException(e);
      }
    }

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

      final PrimitiveType that = (PrimitiveType)o;

      return type == that.type;
    }

    @Override
    public int hashCode() {
      return type;
    }
  }

  public static class ArrayType implements AbstractType {
    public final AbstractType elementType;

    public AbstractType getDeepElementType() {
      AbstractType current = this;

      while (current instanceof ArrayType) {
        current = ((ArrayType)current).elementType;
      }

      return current;
    }

    @Override
    public String getDescr(final DependencyContext context) {
      return "[" + elementType.getDescr(context);
    }

    @Override
    public void updateClassUsages(final DependencyContext context, final int owner, final Set<UsageRepr.Usage> s) {
      elementType.updateClassUsages(context, owner, s);
    }

    ArrayType(final AbstractType elementType) {
      this.elementType = elementType;
    }

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

      final ArrayType arrayType = (ArrayType)o;

      return elementType.equals(arrayType.elementType);
    }

    @Override
    public int hashCode() {
      return elementType.hashCode();
    }

    @Override
    public void save(final DataOutput out) {
      try {
        out.writeByte(ARRAY_TYPE);
        elementType.save(out);
      }
      catch (IOException e) {
        throw new BuildDataCorruptedException(e);
      }
    }
  }

  public static class ClassType implements AbstractType {
    public final int className;
    public final AbstractType[] typeArgs;

    @Override
    public String getDescr(final DependencyContext context) {
      return "L" + context.getValue(className) + ";";
    }

    @Override
    public void updateClassUsages(final DependencyContext context, final int owner, final Set<UsageRepr.Usage> s) {
      s.add(UsageRepr.createClassUsage(context, className));
    }

    ClassType(final int className) {
      this.className = className;
      typeArgs = EMPTY_TYPE_ARRAY;
    }

    ClassType(final DependencyContext context, final DataInput in) {
      try {
        className = DataInputOutputUtil.readINT(in);
        final int size = DataInputOutputUtil.readINT(in);
        if (size == 0) {
          typeArgs = EMPTY_TYPE_ARRAY;
        }
        else {
          typeArgs = new AbstractType[size];
          final DataExternalizer<AbstractType> externalizer = externalizer(context);
          for (int i = 0; i < size; i++) {
            typeArgs[i] = externalizer.read(in);
          }
        }
      }
      catch (IOException e) {
        throw new BuildDataCorruptedException(e);
      }
    }

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

      final ClassType classType = (ClassType)o;

      if (className != classType.className) return false;
      if (!Arrays.equals(typeArgs, classType.typeArgs)) return false;

      return true;
    }

    @Override
    public int hashCode() {
      int result = className;
      result = 31 * result + (typeArgs != null ? Arrays.hashCode(typeArgs) : 0);
      return result;
    }

    @Override
    public void save(final DataOutput out) {
      try {
        out.writeByte(CLASS_TYPE);
        DataInputOutputUtil.writeINT(out, className);
        DataInputOutputUtil.writeINT(out, typeArgs.length);
        for (AbstractType t : typeArgs) {
          t.save(out);
        }
      }
      catch (IOException e) {
        throw new BuildDataCorruptedException(e);
      }
    }
  }

  public static Collection<AbstractType> createClassType(final DependencyContext context,
                                                         final String[] args,
                                                         final Collection<AbstractType> acc) {
    if (args != null) {
      for (String a : args) {
        acc.add(createClassType(context, context.get(a)));
      }
    }

    return acc;
  }

  public static ClassType createClassType(final DependencyContext context, final int s) {
    return (ClassType)context.getType(new ClassType(s));
  }

  public static AbstractType getType(final DependencyContext context, final int descr) {
    final Type t = Type.getType(context.getValue(descr));

    switch (t.getSort()) {
      case Type.OBJECT:
        return context.getType(new ClassType(context.get(StringUtil.replaceChar(t.getClassName(), '.', '/'))));

      case Type.ARRAY:
        return context.getType(new ArrayType(getType(context, t.getElementType())));

      default:
        return context.getType(new PrimitiveType(descr));
    }
  }

  public static AbstractType getType(final DependencyContext context, final Type t) {
    return getType(context, context.get(t.getDescriptor()));
  }

  public static AbstractType[] getType(final DependencyContext context, final Type[] t) {
    if(t.length == 0) return AbstractType.EMPTY_TYPE_ARRAY;
    final AbstractType[] r = new AbstractType[t.length];

    for (int i = 0; i < r.length; i++) {
      r[i] = getType(context, t[i]);
    }

    return r;
  }

  public static DataExternalizer<AbstractType> externalizer(final DependencyContext context) {
    return new DataExternalizer<AbstractType>() {
      @Override
      public void save(@NotNull final DataOutput out, final AbstractType value) throws IOException {
        value.save(out);
      }

      @Override
      public AbstractType read(@NotNull final DataInput in) throws IOException {
        AbstractType elementType;
        int level = 0;

        loop:
        while (true) {
          final byte tag = in.readByte();
          switch (tag) {
            case PRIMITIVE_TYPE:
              elementType = context.getType(new PrimitiveType(in));
              break loop;

            case CLASS_TYPE:
              elementType = context.getType(new ClassType(context, in));
              break loop;

            case ARRAY_TYPE:
              level++;
              break;

            default :
              System.out.println("Unknown type!");
          }
        }

        for (int i = 0; i < level; i++) {
          elementType = context.getType(new ArrayType(elementType));
        }

        return elementType;
      }
    };
  }
}
