// 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 RetraceClassResult(ClassReference obfuscatedReference, ClassNamingForNameMapper mapper) {
    this.obfuscatedReference = obfuscatedReference;
    this.mapper = mapper;
  }

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

  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));
        });
    return elementBox.get();
  }

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

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

  @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);
  }

  public static class Element {

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

    public Element(
        RetraceClassResult classResult,
        ClassReference classReference,
        ClassNamingForNameMapper mapper) {
      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);
    }
  }
}
