/*
 * Copyright 2009 Google Inc.
 *
 * 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.google.gwt.dev.javac.asm;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.dev.javac.Resolver;
import com.google.gwt.dev.javac.TypeParameterLookup;
import com.google.gwt.dev.javac.typemodel.JClassType;
import com.google.gwt.dev.javac.typemodel.JRealClassType;
import com.google.gwt.dev.javac.typemodel.JTypeParameter;

import org.objectweb.asm.signature.SignatureVisitor;

import java.util.ArrayList;
import java.util.List;

/**
 * Signature visitor that resolves all the type variables and their bounds for a
 * given class.
 */
public class ResolveClassSignature extends EmptySignatureVisitor {

  private ArrayList<JType[]> bounds = null;
  private JTypeParameter currentParam = null;
  private final List<JType[]> interfaces = new ArrayList<JType[]>();
  private final TreeLogger logger;

  private final TypeParameterLookup lookup;
  private final Resolver resolver;
  private final JType[] superClass = new JType[1];
  private final JRealClassType type;

  public ResolveClassSignature(Resolver resolver, TreeLogger logger, JRealClassType type,
      TypeParameterLookup lookup) {
    this.resolver = resolver;
    this.logger = logger;
    this.type = type;
    this.lookup = lookup;
  }

  public void finish() {
    if (currentParam != null) {
      int n = bounds.size();
      JClassType[] boundTypes = new JClassType[n];
      for (int i = 0; i < n; ++i) {
        boundTypes[i] = (JClassType) bounds.get(i)[0];
      }
      currentParam.setBounds(boundTypes);
      currentParam = null;
      // TODO(jat): remove after debugging phase
      bounds = null;
    }
    if (superClass[0] != null) {
      if (type.isInterface() != null) {
        // The generic signature contains a superclass for interfaces,
        // but TypeOracle doesn't like that -- verify that we were
        // told Object is the superclass and ignore it.
        assert superClass[0].equals(resolver.getTypeOracle().getJavaLangObject());
      } else {
        resolver.setSuperClass(type, (JClassType) superClass[0]);
      }
      superClass[0] = null;
    }
    for (JType[] intfRef : interfaces) {
      if (intfRef[0] != null) {
        resolver.addImplementedInterface(type, (JClassType) intfRef[0]);
      }
    }
    interfaces.clear();
  }

  @Override
  public SignatureVisitor visitArrayType() {
    throw new IllegalStateException(
        "visitArrayType called on ResolveClassTypeVariables");
  }

  @Override
  public SignatureVisitor visitClassBound() {
    JType[] bound = new JType[1];
    bounds.add(bound);
    return new ResolveTypeSignature(resolver, logger, bound, lookup, null);
  }

  @Override
  public void visitFormalTypeParameter(String name) {
    finish();
    currentParam = lookup.lookup(name);
    bounds = new ArrayList<JType[]>();
  }

  @Override
  public SignatureVisitor visitInterface() {
    finish();
    JType[] intf = new JType[1];
    interfaces.add(intf);
    return new ResolveTypeSignature(resolver, logger, intf, lookup, null);
  }

  @Override
  public SignatureVisitor visitInterfaceBound() {
    JType[] bound = new JType[1];
    bounds.add(bound);
    return new ResolveTypeSignature(resolver, logger, bound, lookup, null);
  }

  @Override
  public SignatureVisitor visitSuperclass() {
    finish();
    return new ResolveTypeSignature(resolver, logger, superClass, lookup, null);
  }
}
