/*
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * 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.turbine.binder;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.turbine.binder.bound.HeaderBoundClass;
import com.google.turbine.binder.bound.PackageSourceBoundClass;
import com.google.turbine.binder.bound.SourceHeaderBoundClass;
import com.google.turbine.binder.env.Env;
import com.google.turbine.binder.env.LazyEnv.LazyBindingError;
import com.google.turbine.binder.lookup.LookupKey;
import com.google.turbine.binder.lookup.LookupResult;
import com.google.turbine.binder.sym.ClassSymbol;
import com.google.turbine.binder.sym.TyVarSymbol;
import com.google.turbine.diag.TurbineError.ErrorKind;
import com.google.turbine.diag.TurbineLog.TurbineLogWithSource;
import com.google.turbine.model.TurbineTyKind;
import com.google.turbine.tree.Tree;
import com.google.turbine.tree.Tree.ClassTy;
import java.util.ArrayDeque;
import org.jspecify.nullness.Nullable;

/** Type hierarchy binding. */
public class HierarchyBinder {

  /** Binds the type hierarchy (superclasses and interfaces) for a single class. */
  public static SourceHeaderBoundClass bind(
      TurbineLogWithSource log,
      ClassSymbol origin,
      PackageSourceBoundClass base,
      Env<ClassSymbol, ? extends HeaderBoundClass> env) {
    return new HierarchyBinder(log, origin, base, env).bind();
  }

  private final TurbineLogWithSource log;
  private final ClassSymbol origin;
  private final PackageSourceBoundClass base;
  private final Env<ClassSymbol, ? extends HeaderBoundClass> env;

  private HierarchyBinder(
      TurbineLogWithSource log,
      ClassSymbol origin,
      PackageSourceBoundClass base,
      Env<ClassSymbol, ? extends HeaderBoundClass> env) {
    this.log = log;
    this.origin = origin;
    this.base = base;
    this.env = env;
  }

  private SourceHeaderBoundClass bind() {
    Tree.TyDecl decl = base.decl();

    ClassSymbol superclass;
    if (decl.xtnds().isPresent()) {
      superclass = resolveClass(decl.xtnds().get());
      if (origin.equals(superclass)) {
        log.error(decl.xtnds().get().position(), ErrorKind.CYCLIC_HIERARCHY, origin);
      }
    } else {
      switch (decl.tykind()) {
        case ENUM:
          superclass = ClassSymbol.ENUM;
          break;
        case INTERFACE:
        case ANNOTATION:
        case CLASS:
          superclass = !origin.equals(ClassSymbol.OBJECT) ? ClassSymbol.OBJECT : null;
          break;
        case RECORD:
          superclass = ClassSymbol.RECORD;
          break;
        default:
          throw new AssertionError(decl.tykind());
      }
    }

    ImmutableList.Builder<ClassSymbol> interfaces = ImmutableList.builder();
    if (!decl.impls().isEmpty()) {
      for (Tree.ClassTy i : decl.impls()) {
        ClassSymbol result = resolveClass(i);
        if (result == null) {
          continue;
        }
        if (origin.equals(result)) {
          log.error(i.position(), ErrorKind.CYCLIC_HIERARCHY, origin);
        }
        interfaces.add(result);
      }
    } else {
      if (decl.tykind() == TurbineTyKind.ANNOTATION) {
        interfaces.add(ClassSymbol.ANNOTATION);
      }
    }

    ImmutableMap.Builder<String, TyVarSymbol> typeParameters = ImmutableMap.builder();
    for (Tree.TyParam p : decl.typarams()) {
      typeParameters.put(p.name().value(), new TyVarSymbol(origin, p.name().value()));
    }

    return new SourceHeaderBoundClass(base, superclass, interfaces.build(), typeParameters.build());
  }

  /**
   * Resolves the {@link ClassSymbol} for the given {@link Tree.ClassTy}, with handling for
   * non-canonical qualified type names.
   */
  private @Nullable ClassSymbol resolveClass(Tree.ClassTy ty) {
    // flatten a left-recursive qualified type name to its component simple names
    // e.g. Foo<Bar>.Baz -> ["Foo", "Bar"]
    ArrayDeque<Tree.Ident> flat = new ArrayDeque<>();
    for (Tree.ClassTy curr = ty; curr != null; curr = curr.base().orElse(null)) {
      flat.addFirst(curr.name());
    }
    // Resolve the base symbol in the qualified name.
    LookupResult result = lookup(ty, new LookupKey(ImmutableList.copyOf(flat)));
    if (result == null) {
      log.error(ty.position(), ErrorKind.CANNOT_RESOLVE, Joiner.on('.').join(flat));
      return null;
    }
    // Resolve pieces in the qualified name referring to member types.
    // This needs to consider member type declarations inherited from supertypes and interfaces.
    ClassSymbol sym = (ClassSymbol) result.sym();
    for (Tree.Ident bit : result.remaining()) {
      sym = resolveNext(ty, sym, bit);
      if (sym == null) {
        break;
      }
    }
    return sym;
  }

  private @Nullable ClassSymbol resolveNext(ClassTy ty, ClassSymbol sym, Tree.Ident bit) {
    ClassSymbol next;
    try {
      next = Resolve.resolve(env, origin, sym, bit);
    } catch (LazyBindingError e) {
      log.error(ty.position(), ErrorKind.CYCLIC_HIERARCHY, e.getMessage());
      return null;
    }
    if (next == null) {
      log.error(
          bit.position(),
          ErrorKind.SYMBOL_NOT_FOUND,
          new ClassSymbol(sym.binaryName() + '$' + bit));
    }
    return next;
  }

  /** Resolve a qualified type name to a symbol. */
  private @Nullable LookupResult lookup(Tree tree, LookupKey lookup) {
    // Handle any lexically enclosing class declarations (if we're binding a member class).
    // We could build out scopes for this, but it doesn't seem worth it. (And sharing the scopes
    // with other members of the same enclosing declaration would be complicated.)
    for (ClassSymbol curr = base.owner(); curr != null; curr = env.getNonNull(curr).owner()) {
      ClassSymbol result;
      try {
        result = Resolve.resolve(env, origin, curr, lookup.first());
      } catch (LazyBindingError e) {
        log.error(tree.position(), ErrorKind.CYCLIC_HIERARCHY, e.getMessage());
        result = null;
      }
      if (result != null) {
        return new LookupResult(result, lookup);
      }
    }
    // Fall back to the top-level scopes for the compilation unit (imports, same package, then
    // qualified name resolution).
    return base.scope().lookup(lookup, Resolve.resolveFunction(env, origin));
  }
}
