// Copyright (c) 2020, 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 static com.android.tools.r8.utils.codeinspector.KmTypeSubject.getDescriptorFromKmType;

import com.android.tools.r8.references.Reference;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import kotlinx.metadata.KmDeclarationContainer;
import kotlinx.metadata.KmExtensionType;
import kotlinx.metadata.KmFunction;
import kotlinx.metadata.KmFunctionExtensionVisitor;
import kotlinx.metadata.KmFunctionVisitor;
import kotlinx.metadata.KmProperty;
import kotlinx.metadata.KmPropertyExtensionVisitor;
import kotlinx.metadata.KmPropertyVisitor;
import kotlinx.metadata.KmType;
import kotlinx.metadata.jvm.JvmFieldSignature;
import kotlinx.metadata.jvm.JvmFunctionExtensionVisitor;
import kotlinx.metadata.jvm.JvmMethodSignature;
import kotlinx.metadata.jvm.JvmPropertyExtensionVisitor;

public interface FoundKmDeclarationContainerSubject extends KmDeclarationContainerSubject {

  CodeInspector codeInspector();
  KmDeclarationContainer getKmDeclarationContainer();

  @Override
  default List<String> getParameterTypeDescriptorsInFunctions() {
    return getKmDeclarationContainer().getFunctions().stream()
        .flatMap(kmFunction ->
            kmFunction.getValueParameters().stream()
                .map(kmValueParameter -> getDescriptorFromKmType(kmValueParameter.getType()))
                .filter(Objects::nonNull))
        .collect(Collectors.toList());
  }

  @Override
  default List<String> getReturnTypeDescriptorsInFunctions() {
    return getKmDeclarationContainer().getFunctions().stream()
        .map(kmFunction -> getDescriptorFromKmType(kmFunction.getReturnType()))
        .filter(Objects::nonNull)
        .collect(Collectors.toList());
  }

  @Override
  default List<String> getReturnTypeDescriptorsInProperties() {
    return getKmDeclarationContainer().getProperties().stream()
        .map(kmProperty -> getDescriptorFromKmType(kmProperty.getReturnType()))
        .filter(Objects::nonNull)
        .collect(Collectors.toList());
  }

  // TODO(b/145824437): This is a dup of KotlinMetadataJvmExtensionUtils$KmFunctionProcessor
  class KmFunctionProcessor {
    // Custom name via @JvmName("..."). Otherwise, null.
    JvmMethodSignature signature = null;

    KmFunctionProcessor(KmFunction kmFunction) {
      kmFunction.accept(new KmFunctionVisitor() {
        @Override
        public KmFunctionExtensionVisitor visitExtensions(KmExtensionType type) {
          if (type != JvmFunctionExtensionVisitor.TYPE) {
            return null;
          }
          return new JvmFunctionExtensionVisitor() {
            @Override
            public void visit(JvmMethodSignature desc) {
              assert signature == null : signature.asString();
              signature = desc;
            }
          };
        }
      });
      // We don't check Kotlin types in tests, but be aware of the relocation issue.
      // See b/70169921#comment57 for more details.
    }
  }

  // TODO(b/151194869): Search both original and renamed names.
  default KmFunctionSubject kmFunctionOrExtensionWithUniqueName(String name, boolean isExtension) {
    KmFunction foundFunction = null;
    for (KmFunction kmFunction : getKmDeclarationContainer().getFunctions()) {
      if (KmFunctionSubject.isExtension(kmFunction) != isExtension) {
        continue;
      }
      if (kmFunction.getName().equals(name)) {
        foundFunction = kmFunction;
        break;
      }
      KmFunctionProcessor kmFunctionProcessor = new KmFunctionProcessor(kmFunction);
      if (kmFunctionProcessor.signature != null
          && kmFunctionProcessor.signature.getName().equals(name)) {
        foundFunction = kmFunction;
        break;
      }
    }
    if (foundFunction != null) {
      return new FoundKmFunctionSubject(codeInspector(), foundFunction);
    }
    return new AbsentKmFunctionSubject();
  }

  @Override
  default KmFunctionSubject kmFunctionWithUniqueName(String name) {
    return kmFunctionOrExtensionWithUniqueName(name, false);
  }

  @Override
  default KmFunctionSubject kmFunctionExtensionWithUniqueName(String name) {
    return kmFunctionOrExtensionWithUniqueName(name, true);
  }

  @Override
  default List<KmFunctionSubject> getFunctions() {
    return getKmDeclarationContainer().getFunctions().stream()
        .map(kmFunction -> new FoundKmFunctionSubject(codeInspector(), kmFunction))
        .collect(Collectors.toList());
  }

  default ClassSubject getClassSubjectFromDescriptor(String descriptor) {
    return codeInspector().clazz(Reference.classFromDescriptor(descriptor));
  }

  default ClassSubject getClassSubjectFromKmType(KmType kmType) {
    String descriptor = getDescriptorFromKmType(kmType);
    if (descriptor == null) {
      return new AbsentClassSubject();
    }
    return getClassSubjectFromDescriptor(descriptor);
  }

  @Override
  default List<ClassSubject> getParameterTypesInFunctions() {
    return getKmDeclarationContainer().getFunctions().stream()
        .flatMap(kmFunction ->
            kmFunction.getValueParameters().stream()
                .map(kmValueParameter -> getClassSubjectFromKmType(kmValueParameter.getType()))
                .filter(ClassSubject::isPresent))
        .collect(Collectors.toList());
  }

  @Override
  default List<ClassSubject> getReturnTypesInFunctions() {
    return getKmDeclarationContainer().getFunctions().stream()
        .map(kmFunction -> getClassSubjectFromKmType(kmFunction.getReturnType()))
        .filter(ClassSubject::isPresent)
        .collect(Collectors.toList());
  }

  // TODO(b/145824437): This is a dup of KotlinMetadataJvmExtensionUtils$KmPropertyProcessor
  class KmPropertyProcessor {
    JvmFieldSignature fieldSignature = null;
    // Custom getter via @get:JvmName("..."). Otherwise, null.
    JvmMethodSignature getterSignature = null;
    // Custom getter via @set:JvmName("..."). Otherwise, null.
    JvmMethodSignature setterSignature = null;

    KmPropertyProcessor(KmProperty kmProperty) {
      kmProperty.accept(new KmPropertyVisitor() {
        @Override
        public KmPropertyExtensionVisitor visitExtensions(KmExtensionType type) {
          if (type != JvmPropertyExtensionVisitor.TYPE) {
            return null;
          }
          return new JvmPropertyExtensionVisitor() {
            @Override
            public void visit(
                int flags,
                JvmFieldSignature fieldDesc,
                JvmMethodSignature getterDesc,
                JvmMethodSignature setterDesc) {
              assert fieldSignature == null : fieldSignature.asString();
              fieldSignature = fieldDesc;
              assert getterSignature == null : getterSignature.asString();
              getterSignature = getterDesc;
              assert setterSignature == null : setterSignature.asString();
              setterSignature = setterDesc;
            }
          };
        }
      });
      // We don't check Kotlin types in tests, but be aware of the relocation issue.
      // See b/70169921#comment57 for more details.
    }
  }

  default KmPropertySubject kmPropertyOrExtensionWithUniqueName(String name, boolean isExtension) {
    KmProperty foundProperty = null;
    for (KmProperty kmProperty : getKmDeclarationContainer().getProperties()) {
      if (KmPropertySubject.isExtension(kmProperty) != isExtension) {
        continue;
      }
      if (kmProperty.getName().equals(name)) {
        foundProperty = kmProperty;
        break;
      }
      KmPropertyProcessor kmPropertyProcessor = new KmPropertyProcessor(kmProperty);
      if (kmPropertyProcessor.fieldSignature != null
          && kmPropertyProcessor.fieldSignature.getName().equals(name)) {
        foundProperty = kmProperty;
        break;
      }
      if (kmPropertyProcessor.getterSignature != null
          && kmPropertyProcessor.getterSignature.getName().equals(name)) {
        foundProperty = kmProperty;
        break;
      }
      if (kmPropertyProcessor.setterSignature != null
          && kmPropertyProcessor.setterSignature.getName().equals(name)) {
        foundProperty = kmProperty;
        break;
      }
    }
    if (foundProperty != null) {
      return new FoundKmPropertySubject(codeInspector(), foundProperty);
    }
    return new AbsentKmPropertySubject();
  }

  @Override
  default KmPropertySubject kmPropertyWithUniqueName(String name) {
    return kmPropertyOrExtensionWithUniqueName(name, false);
  }

  @Override
  default KmPropertySubject kmPropertyExtensionWithUniqueName(String name) {
    return kmPropertyOrExtensionWithUniqueName(name, true);
  }

  @Override
  default List<KmPropertySubject> getProperties() {
    return getKmDeclarationContainer().getProperties().stream()
        .map(kmProperty -> new FoundKmPropertySubject(codeInspector(), kmProperty))
        .collect(Collectors.toList());
  }

  @Override
  default List<ClassSubject> getReturnTypesInProperties() {
    return getKmDeclarationContainer().getProperties().stream()
        .map(kmProperty -> getClassSubjectFromKmType(kmProperty.getReturnType()))
        .filter(ClassSubject::isPresent)
        .collect(Collectors.toList());
  }
}
