/*
 * 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.util;

import com.intellij.openapi.util.Condition;
import com.intellij.util.containers.ConcurrentFactoryMap;
import net.sf.cglib.core.*;
import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;

import java.lang.reflect.Modifier;

/**
 * @author peter
 */
public class InstanceofCheckerGenerator {
  private static final InstanceofCheckerGenerator ourInstance;

  static {
    try {
      ourInstance = new InstanceofCheckerGenerator();
    }
    catch (Throwable e) {
      throw new RuntimeException(e);
    }
  }

  public static InstanceofCheckerGenerator getInstance() {
    return ourInstance;
  }

  private final ConcurrentFactoryMap<Class, Condition<Object>> myCache = new ConcurrentFactoryMap<Class, Condition<Object>>() {
    @Override
    protected Condition<Object> create(final Class key) {
      if (key.isAnonymousClass() || Modifier.isPrivate(key.getModifiers())) {
        return new Condition<Object>() {
          @Override
          public boolean value(Object o) {
            return key.isInstance(o);
          }
        };
      }

      return new InstanceofClassGenerator(key).createClass();
    }
  };

  @NotNull
  public Condition<Object> getInstanceofChecker(final Class<?> someClass) {
    return myCache.get(someClass);
  }

  private static String toInternalName(Class<?> someClass) {
    return someClass.getName().replace('.', '/');
  }

  private static class InstanceofClassGenerator extends AbstractClassGenerator {
    private static final Source SOURCE = new Source("IntellijInstanceof");
    private final Class<?> myCheckedClass;

    public InstanceofClassGenerator(Class<?> checkedClass) {
      super(SOURCE);
      myCheckedClass = checkedClass;
    }

    @Override
    protected ClassLoader getDefaultClassLoader() {
      return myCheckedClass.getClassLoader();
    }

    public Condition<Object> createClass() {
      return (Condition<Object>)super.create(myCheckedClass);
    }

    @Override
    protected Object firstInstance(Class type) throws Exception {
      return type.newInstance();
    }

    @Override
    protected Object nextInstance(Object instance) throws Exception {
      return instance;
    }

    @Override
    public void generateClass(ClassVisitor classVisitor) throws Exception {
      ClassEmitter cv = new ClassEmitter(classVisitor);

      cv.visit(Constants.V1_2, Modifier.PUBLIC, "com/intellij/util/InstanceofChecker$$$$$" + myCheckedClass.getName().replace('.', '$'), null, toInternalName(Object.class), new String[]{toInternalName(Condition.class)});
      cv.visitSource(Constants.SOURCE_FILE, null);
      final Signature signature = new Signature("<init>", "()V");
      final CodeEmitter cons = cv.begin_method(Modifier.PUBLIC, signature, new Type[0]);
      cons.load_this();
      cons.dup();
      cons.super_invoke_constructor(signature);
      cons.return_value();
      cons.end_method();

      final CodeEmitter e = cv.begin_method(Modifier.PUBLIC, new Signature("value", "(L" + toInternalName(Object.class) + ";)Z"), new Type[0]);
      e.load_arg(0);
      e.instance_of(Type.getType(myCheckedClass));

      Label fail = e.make_label();
      e.if_jump(CodeEmitter.EQ, fail);
      e.push(true);
      e.return_value();

      e.mark(fail);
      e.push(false);
      e.return_value();
      e.end_method();

      cv.visitEnd();
    }
  }
}
