// Copyright (c) 2017, 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;

import static com.android.tools.r8.utils.MapConsumerUtils.wrapExistingMapConsumer;

import com.android.tools.r8.BaseCompilerCommand;
import com.android.tools.r8.ByteDataView;
import com.android.tools.r8.ClassFileConsumer;
import com.android.tools.r8.DataDirectoryResource;
import com.android.tools.r8.DataEntryResource;
import com.android.tools.r8.DataResourceConsumer;
import com.android.tools.r8.DexFilePerClassFileConsumer;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.DexIndexedConsumer.ForwardingConsumer;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.ProgramConsumer;
import com.android.tools.r8.ResourceException;
import com.android.tools.r8.StringConsumer;
import com.android.tools.r8.naming.MapConsumer;
import com.android.tools.r8.naming.ProguardMapStringConsumer;
import com.android.tools.r8.origin.Origin;
import com.google.common.io.ByteStreams;
import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;

public class AndroidAppConsumers {

  private final AndroidApp.Builder builder = AndroidApp.builder();
  private boolean closed = false;

  private ProgramConsumer programConsumer = null;
  private MapConsumer mapConsumer = null;

  public AndroidAppConsumers() {
    // Nothing to do.
  }

  public AndroidAppConsumers(BaseCompilerCommand.Builder<?, ?> builder) {
    builder.setProgramConsumer(wrapProgramConsumer(builder.getProgramConsumer()));
  }

  public AndroidAppConsumers(InternalOptions options) {
    options.programConsumer = wrapProgramConsumer(options.programConsumer);
    options.mapConsumer = wrapProguardMapConsumer(options.mapConsumer);
  }

  public ProgramConsumer wrapProgramConsumer(ProgramConsumer consumer) {
    assert programConsumer == null;
    if (consumer instanceof ClassFileConsumer) {
      wrapClassFileConsumer((ClassFileConsumer) consumer);
    } else if (consumer instanceof DexIndexedConsumer) {
      wrapDexIndexedConsumer((DexIndexedConsumer) consumer);
    } else if (consumer instanceof DexFilePerClassFileConsumer) {
      wrapDexFilePerClassFileConsumer((DexFilePerClassFileConsumer) consumer);
    } else {
      // TODO(zerny): Refine API to disallow running without a program consumer.
      assert consumer == null;
      wrapDexIndexedConsumer(null);
    }
    assert programConsumer != null;
    return programConsumer;
  }

  public MapConsumer wrapProguardMapConsumer(MapConsumer consumer) {
    assert mapConsumer == null;
    if (consumer != null) {
      mapConsumer =
          wrapExistingMapConsumer(
              consumer,
              ProguardMapStringConsumer.builder()
                  .setStringConsumer(
                      new StringConsumer() {
                        StringBuilder stringBuilder = null;

                        @Override
                        public void accept(String string, DiagnosticsHandler handler) {
                          if (stringBuilder == null) {
                            stringBuilder = new StringBuilder();
                          }
                          stringBuilder.append(string);
                        }

                        @Override
                        public void finished(DiagnosticsHandler handler) {
                          if (stringBuilder != null) {
                            builder.setProguardMapOutputData(stringBuilder.toString());
                          }
                        }
                      })
                  .build());
    }
    return mapConsumer;
  }

  public DexIndexedConsumer wrapDexIndexedConsumer(DexIndexedConsumer consumer) {
    assert programConsumer == null;
    DexIndexedConsumer wrapped =
        new ForwardingConsumer(consumer) {

          // Sort the files by id so that their order is deterministic. Some tests depend on this.
          private Int2ReferenceSortedMap<DescriptorsWithContents> files =
              new Int2ReferenceAVLTreeMap<>();

          @Override
          public void accept(
              int fileIndex,
              ByteDataView data,
              Set<String> descriptors,
              DiagnosticsHandler handler) {
            super.accept(fileIndex, data, descriptors, handler);
            addDexFile(fileIndex, data.copyByteData(), descriptors);
          }

          @Override
          public void finished(DiagnosticsHandler handler) {
            super.finished(handler);
            if (!closed) {
              closed = true;
              files.forEach((v, d) -> builder.addDexProgramData(d.contents, d.descriptors));
              files = null;
            } else {
              assert getDataResourceConsumer() != null;
            }
          }

          @Override
          public DataResourceConsumer getDataResourceConsumer() {
            DataResourceConsumer dataResourceConsumer =
                consumer != null ? consumer.getDataResourceConsumer() : null;
            return new DataResourceConsumer() {

              @Override
              public void accept(
                  DataDirectoryResource directory, DiagnosticsHandler diagnosticsHandler) {
                builder.addDataResource(
                    DataDirectoryResource.fromName(directory.getName(), directory.getOrigin()));
                if (dataResourceConsumer != null) {
                  dataResourceConsumer.accept(directory, diagnosticsHandler);
                }
              }

              @Override
              public void accept(DataEntryResource file, DiagnosticsHandler diagnosticsHandler) {
                try {
                  byte[] bytes = ByteStreams.toByteArray(file.getByteStream());
                  DataEntryResource copy =
                      DataEntryResource.fromBytes(bytes, file.getName(), file.getOrigin());
                  builder.addDataResource(copy);
                  if (dataResourceConsumer != null) {
                    dataResourceConsumer.accept(copy, diagnosticsHandler);
                  }
                } catch (IOException | ResourceException e) {
                  throw new RuntimeException(e);
                }
              }

              @Override
              public void finished(DiagnosticsHandler handler) {
                if (dataResourceConsumer != null) {
                  dataResourceConsumer.finished(handler);
                }
              }
            };
          }

          synchronized void addDexFile(int fileIndex, byte[] data, Set<String> descriptors) {
            files.put(fileIndex, new DescriptorsWithContents(descriptors, data));
          }
        };
    programConsumer = wrapped;
    return wrapped;
  }

  public DexFilePerClassFileConsumer wrapDexFilePerClassFileConsumer(
      DexFilePerClassFileConsumer consumer) {
    assert programConsumer == null;
    DexFilePerClassFileConsumer wrapped =
        new DexFilePerClassFileConsumer.ForwardingConsumer(consumer) {

          // Sort the files by their name for good measure.
          private TreeMap<String, DescriptorsWithContents> files = new TreeMap<>();

          @Override
          public void accept(
              String primaryClassDescriptor,
              ByteDataView data,
              Set<String> descriptors,
              DiagnosticsHandler handler) {
            super.accept(primaryClassDescriptor, data, descriptors, handler);
            addDexFile(primaryClassDescriptor, data.copyByteData(), descriptors);
          }

          synchronized void addDexFile(
              String primaryClassDescriptor, byte[] data, Set<String> descriptors) {
            files.put(primaryClassDescriptor, new DescriptorsWithContents(descriptors, data));
          }

          @Override
          public void finished(DiagnosticsHandler handler) {
            super.finished(handler);
            if (!closed) {
              closed = true;
              files.forEach((v, d) -> builder.addDexProgramData(d.contents, d.descriptors, v));
              files = null;
            } else {
              assert getDataResourceConsumer() != null;
            }
          }

          @Override
          public DataResourceConsumer getDataResourceConsumer() {
            DataResourceConsumer dataResourceConsumer =
                consumer != null ? consumer.getDataResourceConsumer() : null;
            return new DataResourceConsumer() {

              @Override
              public void accept(
                  DataDirectoryResource directory, DiagnosticsHandler diagnosticsHandler) {
                if (dataResourceConsumer != null) {
                  dataResourceConsumer.accept(directory, diagnosticsHandler);
                }
              }

              @Override
              public void accept(DataEntryResource file, DiagnosticsHandler diagnosticsHandler) {
                try {
                  byte[] bytes = ByteStreams.toByteArray(file.getByteStream());
                  DataEntryResource copy =
                      DataEntryResource.fromBytes(bytes, file.getName(), file.getOrigin());
                  builder.addDataResource(copy);
                  if (dataResourceConsumer != null) {
                    dataResourceConsumer.accept(copy, diagnosticsHandler);
                  }
                } catch (IOException | ResourceException e) {
                  throw new RuntimeException(e);
                }
              }

              @Override
              public void finished(DiagnosticsHandler handler) {
                if (dataResourceConsumer != null) {
                  dataResourceConsumer.finished(handler);
                }
              }
            };
          }
        };
    programConsumer = wrapped;
    return wrapped;
  }

  public ClassFileConsumer wrapClassFileConsumer(ClassFileConsumer consumer) {
    assert programConsumer == null;
    ClassFileConsumer wrapped =
        new ClassFileConsumer.ForwardingConsumer(consumer) {

          private List<DescriptorsWithContents> files = new ArrayList<>();

          @Override
          public void accept(ByteDataView data, String descriptor, DiagnosticsHandler handler) {
            super.accept(data, descriptor, handler);
            addClassFile(data.copyByteData(), descriptor);
          }

          synchronized void addClassFile(byte[] data, String descriptor) {
            files.add(new DescriptorsWithContents(Collections.singleton(descriptor), data));
          }

          @Override
          public void finished(DiagnosticsHandler handler) {
            super.finished(handler);
            if (!closed) {
              closed = true;
              files.forEach(
                  d -> builder.addClassProgramData(d.contents, Origin.unknown(), d.descriptors));
              files = null;
            } else {
              assert getDataResourceConsumer() != null;
            }
          }

          @Override
          public DataResourceConsumer getDataResourceConsumer() {
            DataResourceConsumer dataResourceConsumer =
                consumer != null ? consumer.getDataResourceConsumer() : null;
            return new DataResourceConsumer() {

              @Override
              public void accept(
                  DataDirectoryResource directory, DiagnosticsHandler diagnosticsHandler) {
                builder.addDataResource(
                    DataDirectoryResource.fromName(directory.getName(), directory.getOrigin()));
                if (dataResourceConsumer != null) {
                  dataResourceConsumer.accept(directory, diagnosticsHandler);
                }
              }

              @Override
              public void accept(DataEntryResource file, DiagnosticsHandler diagnosticsHandler) {
                try {
                  byte[] bytes = ByteStreams.toByteArray(file.getByteStream());
                  DataEntryResource copy =
                      DataEntryResource.fromBytes(bytes, file.getName(), file.getOrigin());
                  builder.addDataResource(copy);
                  if (dataResourceConsumer != null) {
                    dataResourceConsumer.accept(copy, diagnosticsHandler);
                  }
                } catch (IOException | ResourceException e) {
                  throw new RuntimeException(e);
                }
              }

              @Override
              public void finished(DiagnosticsHandler handler) {
                if (dataResourceConsumer != null) {
                  dataResourceConsumer.finished(handler);
                }
              }
            };
          }
        };
    programConsumer = wrapped;
    return wrapped;
  }

  public AndroidApp build() {
    assert closed;
    return builder.build();
  }

  private static class DescriptorsWithContents {

    final Set<String> descriptors;
    final byte[] contents;

    private DescriptorsWithContents(Set<String> descriptors, byte[] contents) {
      this.descriptors = descriptors;
      this.contents = contents;
    }
  }
}
