// Copyright (c) 2018, 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.regress.b77496850;

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.code.InvokeStatic;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.dexinspector.ClassSubject;
import com.android.tools.r8.utils.dexinspector.DexInspector;
import com.android.tools.r8.utils.dexinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import org.junit.Test;

public class B77496850 extends TestBase {

  static final String LOGTAG = "";

  // Mock class for the code in PathParser below.
  public static class Path {
    void rLineTo(int x, int y) {
    }
    void cubicTo(float a, float b, float c, float d, float e, float f) {
    }
  }

  // Mock class for the code in PathParser below.
  public static class Log {
    static void w(String x, String y) {
    }
  }

  // Code copied from Android support library:
  // https://android.googlesource.com/platform/frameworks/support/+/9791ac540f94c318f6602123d7000bfc55909b81/compat/src/main/java/android/support/v4/graphics/PathParser.java
  public static class PathParser {

    private static void drawArc(Path p,
        float x0,
        float y0,
        float x1,
        float y1,
        float a,
        float b,
        float theta,
        boolean isMoreThanHalf,
        boolean isPositiveArc) {
      /* Convert rotation angle from degrees to radians */
      double thetaD = Math.toRadians(theta);
      /* Pre-compute rotation matrix entries */
      double cosTheta = Math.cos(thetaD);
      double sinTheta = Math.sin(thetaD);
      /* Transform (x0, y0) and (x1, y1) into unit space */
      /* using (inverse) rotation, followed by (inverse) scale */
      double x0p = (x0 * cosTheta + y0 * sinTheta) / a;
      double y0p = (-x0 * sinTheta + y0 * cosTheta) / b;
      double x1p = (x1 * cosTheta + y1 * sinTheta) / a;
      double y1p = (-x1 * sinTheta + y1 * cosTheta) / b;
      /* Compute differences and averages */
      double dx = x0p - x1p;
      double dy = y0p - y1p;
      double xm = (x0p + x1p) / 2;
      double ym = (y0p + y1p) / 2;
      /* Solve for intersecting unit circles */
      double dsq = dx * dx + dy * dy;
      if (dsq == 0.0) {
        Log.w(LOGTAG, " Points are coincident");
        return; /* Points are coincident */
      }
      double disc = 1.0 / dsq - 1.0 / 4.0;
      if (disc < 0.0) {
        Log.w(LOGTAG, "Points are too far apart " + dsq);
        float adjust = (float) (Math.sqrt(dsq) / 1.99999);
        drawArc(p, x0, y0, x1, y1, a * adjust,
            b * adjust, theta, isMoreThanHalf, isPositiveArc);
        return; /* Points are too far apart */
      }
      double s = Math.sqrt(disc);
      double sdx = s * dx;
      double sdy = s * dy;
      double cx;
      double cy;
      if (isMoreThanHalf == isPositiveArc) {
        cx = xm - sdy;
        cy = ym + sdx;
      } else {
        cx = xm + sdy;
        cy = ym - sdx;
      }
      double eta0 = Math.atan2((y0p - cy), (x0p - cx));
      double eta1 = Math.atan2((y1p - cy), (x1p - cx));
      double sweep = (eta1 - eta0);
      if (isPositiveArc != (sweep >= 0)) {
        if (sweep > 0) {
          sweep -= 2 * Math.PI;
        } else {
          sweep += 2 * Math.PI;
        }
      }
      cx *= a;
      cy *= b;
      double tcx = cx;
      cx = cx * cosTheta - cy * sinTheta;
      cy = tcx * sinTheta + cy * cosTheta;
      arcToBezier(p, cx, cy, a, b, x0, y0, thetaD, eta0, sweep);
    }

    /**
     * Converts an arc to cubic Bezier segments and records them in p.
     *
     * @param p     The target for the cubic Bezier segments
     * @param cx    The x coordinate center of the ellipse
     * @param cy    The y coordinate center of the ellipse
     * @param a     The radius of the ellipse in the horizontal direction
     * @param b     The radius of the ellipse in the vertical direction
     * @param e1x   E(eta1) x coordinate of the starting point of the arc
     * @param e1y   E(eta2) y coordinate of the starting point of the arc
     * @param theta The angle that the ellipse bounding rectangle makes with horizontal plane
     * @param start The start angle of the arc on the ellipse
     * @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse
     */
    private static void arcToBezier(Path p,
        double cx,
        double cy,
        double a,
        double b,
        double e1x,
        double e1y,
        double theta,
        double start,
        double sweep) {
      // Taken from equations at: http://spaceroots.org/documents/ellipse/node8.html
      // and http://www.spaceroots.org/documents/ellipse/node22.html
      // Maximum of 45 degrees per cubic Bezier segment
      int numSegments = (int) Math.ceil(Math.abs(sweep * 4 / Math.PI));
      double eta1 = start;
      double cosTheta = Math.cos(theta);
      double sinTheta = Math.sin(theta);
      double cosEta1 = Math.cos(eta1);
      double sinEta1 = Math.sin(eta1);
      double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
      double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1);
      double anglePerSegment = sweep / numSegments;
      for (int i = 0; i < numSegments; i++) {
        double eta2 = eta1 + anglePerSegment;
        double sinEta2 = Math.sin(eta2);
        double cosEta2 = Math.cos(eta2);
        double e2x = cx + (a * cosTheta * cosEta2) - (b * sinTheta * sinEta2);
        double e2y = cy + (a * sinTheta * cosEta2) + (b * cosTheta * sinEta2);
        double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2;
        double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2;
        double tanDiff2 = Math.tan((eta2 - eta1) / 2);
        double alpha =
            Math.sin(eta2 - eta1) * (Math.sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3;
        double q1x = e1x + alpha * ep1x;
        double q1y = e1y + alpha * ep1y;
        double q2x = e2x - alpha * ep2x;
        double q2y = e2y - alpha * ep2y;
        // Adding this no-op call to workaround a proguard related issue.
        p.rLineTo(0, 0);
        p.cubicTo((float) q1x,
            (float) q1y,
            (float) q2x,
            (float) q2y,
            (float) e2x,
            (float) e2y);
        eta1 = eta2;
        e1x = e2x;
        e1y = e2y;
        ep1x = ep2x;
        ep1y = ep2y;
      }
    }
  }

  // Same code as PathParser above, but with exception handlers in the two methods.
  public static class PathParserWithExceptionHandler {

    private static void drawArc(Path p,
        float x0,
        float y0,
        float x1,
        float y1,
        float a,
        float b,
        float theta,
        boolean isMoreThanHalf,
        boolean isPositiveArc) {
      try {
        /* Convert rotation angle from degrees to radians */
        double thetaD = Math.toRadians(theta);
        /* Pre-compute rotation matrix entries */
        double cosTheta = Math.cos(thetaD);
        double sinTheta = Math.sin(thetaD);
        /* Transform (x0, y0) and (x1, y1) into unit space */
        /* using (inverse) rotation, followed by (inverse) scale */
        double x0p = (x0 * cosTheta + y0 * sinTheta) / a;
        double y0p = (-x0 * sinTheta + y0 * cosTheta) / b;
        double x1p = (x1 * cosTheta + y1 * sinTheta) / a;
        double y1p = (-x1 * sinTheta + y1 * cosTheta) / b;
        /* Compute differences and averages */
        double dx = x0p - x1p;
        double dy = y0p - y1p;
        double xm = (x0p + x1p) / 2;
        double ym = (y0p + y1p) / 2;
        /* Solve for intersecting unit circles */
        double dsq = dx * dx + dy * dy;
        if (dsq == 0.0) {
          Log.w(LOGTAG, " Points are coincident");
          return; /* Points are coincident */
        }
        double disc = 1.0 / dsq - 1.0 / 4.0;
        if (disc < 0.0) {
          Log.w(LOGTAG, "Points are too far apart " + dsq);
          float adjust = (float) (Math.sqrt(dsq) / 1.99999);
          drawArc(p, x0, y0, x1, y1, a * adjust,
              b * adjust, theta, isMoreThanHalf, isPositiveArc);
          return; /* Points are too far apart */
        }
        double s = Math.sqrt(disc);
        double sdx = s * dx;
        double sdy = s * dy;
        double cx;
        double cy;
        if (isMoreThanHalf == isPositiveArc) {
          cx = xm - sdy;
          cy = ym + sdx;
        } else {
          cx = xm + sdy;
          cy = ym - sdx;
        }
        double eta0 = Math.atan2((y0p - cy), (x0p - cx));
        double eta1 = Math.atan2((y1p - cy), (x1p - cx));
        double sweep = (eta1 - eta0);
        if (isPositiveArc != (sweep >= 0)) {
          if (sweep > 0) {
            sweep -= 2 * Math.PI;
          } else {
            sweep += 2 * Math.PI;
          }
        }
        cx *= a;
        cy *= b;
        double tcx = cx;
        cx = cx * cosTheta - cy * sinTheta;
        cy = tcx * sinTheta + cy * cosTheta;
        arcToBezier(p, cx, cy, a, b, x0, y0, thetaD, eta0, sweep);
      } catch (Throwable t) {
        // Ignore.
      }
    }

    /**
     * Converts an arc to cubic Bezier segments and records them in p.
     *
     * @param p     The target for the cubic Bezier segments
     * @param cx    The x coordinate center of the ellipse
     * @param cy    The y coordinate center of the ellipse
     * @param a     The radius of the ellipse in the horizontal direction
     * @param b     The radius of the ellipse in the vertical direction
     * @param e1x   E(eta1) x coordinate of the starting point of the arc
     * @param e1y   E(eta2) y coordinate of the starting point of the arc
     * @param theta The angle that the ellipse bounding rectangle makes with horizontal plane
     * @param start The start angle of the arc on the ellipse
     * @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse
     */
    private static void arcToBezier(Path p,
        double cx,
        double cy,
        double a,
        double b,
        double e1x,
        double e1y,
        double theta,
        double start,
        double sweep) {
      try {
        // Taken from equations at: http://spaceroots.org/documents/ellipse/node8.html
        // and http://www.spaceroots.org/documents/ellipse/node22.html
        // Maximum of 45 degrees per cubic Bezier segment
        int numSegments = (int) Math.ceil(Math.abs(sweep * 4 / Math.PI));
        double eta1 = start;
        double cosTheta = Math.cos(theta);
        double sinTheta = Math.sin(theta);
        double cosEta1 = Math.cos(eta1);
        double sinEta1 = Math.sin(eta1);
        double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
        double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1);
        double anglePerSegment = sweep / numSegments;
        for (int i = 0; i < numSegments; i++) {
          double eta2 = eta1 + anglePerSegment;
          double sinEta2 = Math.sin(eta2);
          double cosEta2 = Math.cos(eta2);
          double e2x = cx + (a * cosTheta * cosEta2) - (b * sinTheta * sinEta2);
          double e2y = cy + (a * sinTheta * cosEta2) + (b * cosTheta * sinEta2);
          double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2;
          double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2;
          double tanDiff2 = Math.tan((eta2 - eta1) / 2);
          double alpha =
              Math.sin(eta2 - eta1) * (Math.sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3;
          double q1x = e1x + alpha * ep1x;
          double q1y = e1y + alpha * ep1y;
          double q2x = e2x - alpha * ep2x;
          double q2y = e2y - alpha * ep2y;
          // Adding this no-op call to workaround a proguard related issue.
          p.rLineTo(0, 0);
          p.cubicTo((float) q1x,
              (float) q1y,
              (float) q2x,
              (float) q2y,
              (float) e2x,
              (float) e2y);
          eta1 = eta2;
          e1x = e2x;
          e1y = e2y;
          ep1x = ep2x;
          ep1y = ep2y;
        }
      } catch (Throwable t) {
        // Ignore.
      }
    }

  }

  // Reproduction from b/77496850.
  public static class Reproduction {
    public int test() {
      int count = 0;
      for (int i = 0; i < 1000; i++){
        count += arcToBezier(1.0, 1.0, 2.0);
      }
      return count;
    }

    private static int arcToBezier(double a, double b, double sweep) {
      int count = 0;

      int numSegments = (int) sweep;

      double cosTheta = 0.5;
      double sinTheta = 0.5;
      double cosEta1 = 0.5;
      double sinEta1 = 0.5;
      double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
      double anglePerSegment = sweep / numSegments;

      for (int i = 0; i < numSegments; i++) {
        count++;
      }
      if (numSegments != count) {
        return 1;
      }
      return 0;
    }

    public static void main(String[] args) {
      for (int i = 0; i < 100; i++) {
        System.out.println(new Reproduction().test());
      }
    }
  }

  // Reproduction from b/77496850 with exception handler.
  public static class ReproductionWithExceptionHandler {
    public int test() {
      int count = 0;
      for (int i = 0; i < 1000; i++){
        count += arcToBezier(1.0, 1.0, 2.0);
      }
      return count;
    }

    private static int arcToBezier(double a, double b, double sweep) {
      try {
        int count = 0;

        int numSegments = (int) sweep;

        double cosTheta = 0.5;
        double sinTheta = 0.5;
        double cosEta1 = 0.5;
        double sinEta1 = 0.5;
        double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
        double anglePerSegment = sweep / numSegments;

        for (int i = 0; i < numSegments; i++) {
          count++;
        }
        if (numSegments != count) {
          return 1;
        }
        return 0;
      } catch (Throwable t) {
        return 1;
      }
    }

    public static void main(String[] args) {
      for (int i = 0; i < 100; i++) {
        System.out.println(new Reproduction().test());
      }
    }
  }

  private int countInvokeDoubleIsNan(DexItemFactory factory, DexCode code) {
    int count = 0;
    DexMethod doubleIsNaN = factory.createMethod(
        factory.createString("Ljava/lang/Double;"),
        factory.createString("isNaN"),
        factory.booleanDescriptor,
        new DexString[]{factory.doubleDescriptor});
    for (int i = 0; i < code.instructions.length; i++) {
      if (code.instructions[i] instanceof InvokeStatic) {
        InvokeStatic invoke = (InvokeStatic) code.instructions[i];
        if (invoke.getMethod() == doubleIsNaN) {
          count++;
        }
      }
    }
    return count;
  }

  private void checkPathParserMethods(AndroidApp app, Class testClass, int a, int b)
      throws Exception {
    DexInspector inspector = new DexInspector(app);
    DexItemFactory factory = inspector.getFactory();
    ClassSubject clazz = inspector.clazz(testClass);
    MethodSubject drawArc = clazz.method(
        "void",
        "drawArc",
        ImmutableList.of(
            getClass().getCanonicalName() + "$Path",
            "float", "float", "float", "float", "float", "float", "float", "boolean", "boolean"));
    MethodSubject arcToBezier = clazz.method(
        "void",
        "arcToBezier",
        ImmutableList.of(
            getClass().getCanonicalName() + "$Path",
            "double", "double", "double", "double", "double", "double",
            "double", "double", "double"));
    assertEquals(a, countInvokeDoubleIsNan(factory, drawArc.getMethod().getCode().asDexCode()));
    assertEquals(b, countInvokeDoubleIsNan(factory, arcToBezier.getMethod().getCode().asDexCode()));
  }

  private void runTestPathParser(
      Tool compiler, Class testClass, AndroidApiLevel apiLevel, int a, int b)
      throws Exception {
    AndroidApp app = readClasses(Path.class, Log.class, testClass);
    if (compiler == Tool.D8) {
      app = compileWithD8(app, o -> o.minApiLevel = apiLevel.getLevel());
    } else {
      assert compiler == Tool.R8;
      app = compileWithR8(app, "-keep class * { *; }", o -> o.minApiLevel = apiLevel.getLevel());
    }
    checkPathParserMethods(app, testClass, a, b);
  }

  @Test
  public void testSupportLibraryPathParser() throws Exception{
    for (Tool tool : Tool.values()) {
      runTestPathParser(tool, PathParser.class, AndroidApiLevel.K, 14, 1);
      runTestPathParser(tool, PathParser.class, AndroidApiLevel.L, 0, 0);
      runTestPathParser(tool, PathParserWithExceptionHandler.class, AndroidApiLevel.K, 14, 1);
      runTestPathParser(tool, PathParserWithExceptionHandler.class, AndroidApiLevel.L, 0, 0);
    }
  }

  private void runTestReproduction(
      Tool compiler, Class testClass, AndroidApiLevel apiLevel, int expectedInvokeDoubleIsNanCount)
      throws Exception {
    AndroidApp app = readClasses(testClass);
    if (compiler == Tool.D8) {
      app = compileWithD8(app, o -> o.minApiLevel = apiLevel.getLevel());
    } else {
      assert compiler == Tool.R8;
      app = compileWithR8(app, "-keep class * { *; }", o -> o.minApiLevel = apiLevel.getLevel());
    }
    DexInspector inspector = new DexInspector(app);
    DexItemFactory factory = inspector.getFactory();
    ClassSubject clazz = inspector.clazz(testClass);
    MethodSubject arcToBezier = clazz.method(
        "int", "arcToBezier", ImmutableList.of("double", "double", "double"));
    assertEquals(
      expectedInvokeDoubleIsNanCount,
      countInvokeDoubleIsNan(factory, arcToBezier.getMethod().getCode().asDexCode()));
  }

  @Test
  public void testReproduction() throws Exception{
    for (Tool tool : Tool.values()) {
      runTestReproduction(tool, Reproduction.class, AndroidApiLevel.K, tool == Tool.D8 ? 1 : 0);
      runTestReproduction(tool, Reproduction.class, AndroidApiLevel.L, 0);
      runTestReproduction(
          tool, ReproductionWithExceptionHandler.class, AndroidApiLevel.K, tool == Tool.D8 ? 1 : 0);
      runTestReproduction(tool, ReproductionWithExceptionHandler.class, AndroidApiLevel.L, 0);
    }
  }
}
