// 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.retrace;

import static com.android.tools.r8.naming.MemberNaming.NoSignature.NO_SIGNATURE;
import static com.android.tools.r8.retrace.RetraceUtils.synthesizeFileName;

import com.android.tools.r8.Keep;
import com.android.tools.r8.naming.ClassNamingForNameMapper;
import com.android.tools.r8.naming.ClassNamingForNameMapper.MappedRangesOfName;
import com.android.tools.r8.naming.MemberNaming;
import com.android.tools.r8.naming.mappinginformation.MappingInformation;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.retrace.RetraceClassResult.Element;
import com.android.tools.r8.utils.Box;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.stream.Stream;

@Keep
public class RetraceClassResult extends Result<Element, RetraceClassResult> {

  private final ClassReference obfuscatedReference;
  private final ClassNamingForNameMapper mapper;
  private final RetraceApi retracer;

  private RetraceClassResult(
      ClassReference obfuscatedReference, ClassNamingForNameMapper mapper, RetraceApi retracer) {
    this.obfuscatedReference = obfuscatedReference;
    this.mapper = mapper;
    this.retracer = retracer;
  }

  static RetraceClassResult create(
      ClassReference obfuscatedReference, ClassNamingForNameMapper mapper, RetraceApi retracer) {
    return new RetraceClassResult(obfuscatedReference, mapper, retracer);
  }

  public RetraceFieldResult lookupField(String fieldName) {
    return lookup(
        fieldName,
        (mapper, name) -> {
          List<MemberNaming> memberNamings = mapper.mappedNamingsByName.get(name);
          if (memberNamings == null || memberNamings.isEmpty()) {
            return null;
          }
          return memberNamings;
        },
        RetraceFieldResult::new);
  }

  public RetraceMethodResult lookupMethod(String methodName) {
    return lookup(
        methodName,
        (mapper, name) -> {
          MappedRangesOfName mappedRanges = mapper.mappedRangesByRenamedName.get(name);
          if (mappedRanges == null || mappedRanges.getMappedRanges().isEmpty()) {
            return null;
          }
          return mappedRanges;
        },
        RetraceMethodResult::new);
  }

  private <T, R> R lookup(
      String name,
      BiFunction<ClassNamingForNameMapper, String, T> lookupFunction,
      ResultConstructor<T, R> constructor) {
    Box<R> elementBox = new Box<>();
    forEach(
        element -> {
          assert !elementBox.isSet();
          T mappedRangesForT = null;
          if (element.mapper != null) {
            mappedRangesForT = lookupFunction.apply(element.mapper, name);
          }
          elementBox.set(constructor.create(element, mappedRangesForT, name, retracer));
        });
    return elementBox.get();
  }

  boolean hasRetraceResult() {
    return mapper != null;
  }

  @Override
  public Stream<Element> stream() {
    return Stream.of(
        new Element(
            this,
            mapper == null ? obfuscatedReference : Reference.classFromTypeName(mapper.originalName),
            mapper,
            false));
  }

  @Override
  public RetraceClassResult forEach(Consumer<Element> resultConsumer) {
    stream().forEach(resultConsumer);
    return this;
  }

  private interface ResultConstructor<T, R> {
    R create(Element element, T mappings, String obfuscatedName, RetraceApi retraceApi);
  }

  public boolean isAmbiguous() {
    // Currently we have no way of producing ambiguous class results.
    return false;
  }

  public static class Element {

    private final RetraceClassResult classResult;
    private final ClassReference classReference;
    private final ClassNamingForNameMapper mapper;

    public Element(
        RetraceClassResult classResult,
        ClassReference classReference,
        ClassNamingForNameMapper mapper,
        boolean isAmbiguous) {
      this.classResult = classResult;
      this.classReference = classReference;
      this.mapper = mapper;
    }

    public ClassReference getClassReference() {
      return classReference;
    }

    public RetraceClassResult getRetraceClassResult() {
      return classResult;
    }

    public RetraceSourceFileResult retraceSourceFile(String sourceFile) {
      if (mapper != null && mapper.getAdditionalMappings().size() > 0) {
        List<MappingInformation> mappingInformations =
            mapper.getAdditionalMappings().get(NO_SIGNATURE);
        if (mappingInformations != null) {
          for (MappingInformation mappingInformation : mappingInformations) {
            if (mappingInformation.isFileNameInformation()) {
              return new RetraceSourceFileResult(
                  mappingInformation.asFileNameInformation().getFileName(), false);
            }
          }
        }
      }
      return new RetraceSourceFileResult(
          synthesizeFileName(
              classReference.getTypeName(),
              classResult.obfuscatedReference.getTypeName(),
              sourceFile,
              mapper != null),
          true);
    }

    public RetraceFieldResult lookupField(String fieldName) {
      return lookup(
          fieldName,
          (mapper, name) -> {
            List<MemberNaming> memberNamings = mapper.mappedNamingsByName.get(name);
            if (memberNamings == null || memberNamings.isEmpty()) {
              return null;
            }
            return memberNamings;
          },
          RetraceFieldResult::new);
    }

    public RetraceMethodResult lookupMethod(String methodName) {
      return lookup(
          methodName,
          (mapper, name) -> {
            MappedRangesOfName mappedRanges = mapper.mappedRangesByRenamedName.get(name);
            if (mappedRanges == null || mappedRanges.getMappedRanges().isEmpty()) {
              return null;
            }
            return mappedRanges;
          },
          RetraceMethodResult::new);
    }

    private <T, R> R lookup(
        String name,
        BiFunction<ClassNamingForNameMapper, String, T> lookupFunction,
        ResultConstructor<T, R> constructor) {
      return constructor.create(
          this,
          mapper != null ? lookupFunction.apply(mapper, name) : null,
          name,
          classResult.retracer);
    }
  }
}
