// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.utils.codeinspector;

import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.kotlin.KotlinMetadataWriter;
import com.android.tools.r8.utils.DescriptorUtils;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import kotlinx.metadata.KmClass;
import kotlinx.metadata.KmDeclarationContainer;
import kotlinx.metadata.KmTypeParameter;

public class FoundKmClassSubject extends KmClassSubject
    implements FoundKmDeclarationContainerSubject {

  private final CodeInspector codeInspector;
  private final DexClass clazz;
  private final KmClass kmClass;

  FoundKmClassSubject(CodeInspector codeInspector, DexClass clazz, KmClass kmClass) {
    this.codeInspector = codeInspector;
    this.clazz = clazz;
    this.kmClass = kmClass;
  }

  @Override
  public String getName() {
    return kmClass.getName();
  }

  @Override
  public DexClass getDexClass() {
    return clazz;
  }

  @Override
  public CodeInspector codeInspector() {
    return codeInspector;
  }

  @Override
  public KmDeclarationContainer getKmDeclarationContainer() {
    return kmClass;
  }

  @Override
  public boolean isPresent() {
    return true;
  }

  @Override
  public boolean isRenamed() {
    return !clazz.type.getInternalName().equals(kmClass.name);
  }

  @Override
  public boolean isSynthetic() {
    // TODO(b/151194785): This should return `true` conditionally if we start synthesizing @Metadata
    //   from scratch.
    return false;
  }

  @Override
  public List<String> getSuperTypeDescriptors() {
    return kmClass.getSupertypes().stream()
        .map(KmTypeSubject::getDescriptorFromKmType)
        .filter(Objects::nonNull)
        .collect(Collectors.toList());
  }

  @Override
  public List<ClassSubject> getSuperTypes() {
    return kmClass.getSupertypes().stream()
        .map(this::getClassSubjectFromKmType)
        .filter(ClassSubject::isPresent)
        .collect(Collectors.toList());
  }

  private String nestClassDescriptor(String nestClassName) {
    return DescriptorUtils.getDescriptorFromClassBinaryName(
        kmClass.name + DescriptorUtils.INNER_CLASS_SEPARATOR + nestClassName);
  }

  @Override
  public List<String> getNestedClassDescriptors() {
    return kmClass.getNestedClasses().stream()
        .map(this::nestClassDescriptor)
        .collect(Collectors.toList());
  }

  @Override
  public List<ClassSubject> getNestedClasses() {
    return kmClass.getNestedClasses().stream()
        .map(this::nestClassDescriptor)
        .map(this::getClassSubjectFromDescriptor)
        .collect(Collectors.toList());
  }

  @Override
  public List<String> getSealedSubclassDescriptors() {
    return kmClass.getSealedSubclasses().stream()
        .map(DescriptorUtils::getDescriptorFromKotlinClassifier)
        .collect(Collectors.toList());
  }

  @Override
  public List<ClassSubject> getSealedSubclasses() {
    return kmClass.getSealedSubclasses().stream()
        .map(DescriptorUtils::getDescriptorFromKotlinClassifier)
        .map(this::getClassSubjectFromDescriptor)
        .collect(Collectors.toList());
  }

  @Override
  public String getCompanionObject() {
    return kmClass.getCompanionObject();
  }

  @Override
  public List<KmTypeParameter> getKmTypeParameters() {
    return kmClass.getTypeParameters();
  }

  @Override
  public CodeInspector getCodeInspector() {
    return codeInspector;
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    KotlinMetadataWriter.appendKmClass("", sb, kmClass);
    return sb.toString();
  }
}
