// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';

import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart';

import 'package:ui/ui.dart' as ui;
import 'package:web_engine_tester/golden_tester.dart';

import '../common/fake_asset_manager.dart';
import '../common/test_initialization.dart';
import 'utils.dart';

const String kGlitchShaderSksl = r'''
{
  "sksl": "// This SkSL shader is autogenerated by spirv-cross.\n\nfloat4 flutter_FragCoord;\n\nuniform vec2 uResolution;\nuniform float uTime;\nuniform shader uTex;\nuniform half2 uTex_size;\n\nvec4 oColor;\n\nvec2 FLT_flutter_local_FlutterFragCoord()\n{\n    return flutter_FragCoord.xy;\n}\n\nfloat FLT_flutter_local_cubicPulse(float c, float w, inout float x)\n{\n    x = abs(x - c);\n    if (x > w)\n    {\n        return 0.0;\n    }\n    x /= w;\n    return 1.0 - ((x * x) * (3.0 - (2.0 * x)));\n}\n\nfloat FLT_flutter_local_twoSin(inout float x)\n{\n    x = (6.4899997711181640625 * x) - 0.64999997615814208984375;\n    float t = ((-0.699999988079071044921875) * sin(6.80000019073486328125 * x)) + (1.39999997615814208984375 * sin(2.900000095367431640625 * x));\n    t = (t / 4.099999904632568359375) + 0.5;\n    return t;\n}\n\nfloat FLT_flutter_local_hash_1d(float v)\n{\n    float u = 50.0 * sin(v * 3000.0);\n    return (2.0 * fract((2.0 * u) * u)) - 1.0;\n}\n\nvoid FLT_main()\n{\n    vec2 uv = vec2(FLT_flutter_local_FlutterFragCoord()) / uResolution;\n    float param = 0.5;\n    float param_1 = 0.0500000007450580596923828125;\n    float param_2 = fract(uTime / 4.0);\n    float _127 = FLT_flutter_local_cubicPulse(param, param_1, param_2);\n    float t_2 = _127;\n    float param_3 = fract(uTime / 5.0);\n    float _134 = FLT_flutter_local_twoSin(param_3);\n    float t_1 = _134;\n    float glitchScale = mix(0.0, 8.0, t_1 + t_2);\n    float aberrationSize = mix(0.0, 5.0, t_1 + t_2);\n    float param_4 = uv.y;\n    float h = FLT_flutter_local_hash_1d(param_4);\n    float hs = sign(h);\n    h = max(h, 0.0);\n    h *= h;\n    h = floor(h + float(0.5)) * hs;\n    uv += (vec2(h * glitchScale, 0.0) / uResolution);\n    vec2 redOffset = vec2(aberrationSize, 0.0) / uResolution;\n    vec2 greenOffset = vec2(0.0) / uResolution;\n    vec2 blueOffset = vec2(-aberrationSize, 0.0) / uResolution;\n    vec2 redUv = uv + redOffset;\n    vec2 greenUv = uv + greenOffset;\n    vec2 blueUv = uv + blueOffset;\n    vec2 ra = uTex.eval(uTex_size *  redUv).xw;\n    vec2 ga = uTex.eval(uTex_size *  greenUv).yw;\n    vec2 ba = uTex.eval(uTex_size *  blueUv).zw;\n    ra.x /= ra.y;\n    ga.x /= ga.y;\n    ba.x /= ba.y;\n    float alpha = max(ra.y, max(ga.y, ba.y));\n    oColor = vec4(ra.x, ga.x, ba.x, 1.0) * alpha;\n}\n\nhalf4 main(float2 iFragCoord)\n{\n      flutter_FragCoord = float4(iFragCoord, 0, 0);\n      FLT_main();\n      return oColor;\n}\n",
  "stage": 1,
  "target_platform": 2,
  "uniforms": [
    {
      "array_elements": 0,
      "bit_width": 32,
      "columns": 1,
      "location": 0,
      "name": "uResolution",
      "rows": 2,
      "type": 10
    },
    {
      "array_elements": 0,
      "bit_width": 32,
      "columns": 1,
      "location": 1,
      "name": "uTime",
      "rows": 1,
      "type": 10
    },
    {
      "array_elements": 0,
      "bit_width": 0,
      "columns": 1,
      "location": 2,
      "name": "uTex",
      "rows": 1,
      "type": 12
    }
  ]
}
''';

void main() {
  internalBootstrapBrowserTest(() => testMain);
}

Future<void> testMain() async {
  setUpUnitTests(
    setUpTestViewDimensions: false,
  );

  late FakeAssetScope assetScope;
  setUp(() {
    assetScope = fakeAssetManager.pushAssetScope();
    assetScope.setAsset(
      'glitch_shader',
      Uint8List.fromList(utf8.encode(kGlitchShaderSksl)).buffer.asByteData()
    );
  });

  tearDown(() {
    fakeAssetManager.popAssetScope(assetScope);
  });

  const ui.Rect drawRegion = ui.Rect.fromLTWH(0, 0, 300, 300);
  const ui.Rect imageRegion = ui.Rect.fromLTWH(0, 0, 150, 150);

  // Emits a set of rendering tests for an image
  // `imageGenerator` should produce an image that is 150x150 pixels.
  void emitImageTests(String name, Future<ui.Image> Function() imageGenerator) {
    group(name, () {
      late ui.Image image;
      setUp(() async {
        image = await imageGenerator();
      });

      tearDown(() {
        image.dispose();
      });

      test('drawImage', () async {
        final ui.Image image = await imageGenerator();

        final ui.PictureRecorder recorder = ui.PictureRecorder();
        final ui.Canvas canvas = ui.Canvas(recorder, drawRegion);
        canvas.drawImage(image, const ui.Offset(100, 100), ui.Paint());

        await drawPictureUsingCurrentRenderer(recorder.endRecording());

        await matchGoldenFile('${name}_canvas_drawImage.png', region: drawRegion);
      });

      test('drawImageRect', () async {
        final ui.Image image = await imageGenerator();

        final ui.PictureRecorder recorder = ui.PictureRecorder();
        final ui.Canvas canvas = ui.Canvas(recorder, drawRegion);
        canvas.drawImageRect(
          image,
          const ui.Rect.fromLTRB(50, 50, 100, 100),
          const ui.Rect.fromLTRB(100, 100, 150, 150),
          ui.Paint()
        );

        await drawPictureUsingCurrentRenderer(recorder.endRecording());

        await matchGoldenFile('${name}_canvas_drawImageRect.png', region: drawRegion);
      });

      test('drawImageNine', () async {
        final ui.Image image = await imageGenerator();

        final ui.PictureRecorder recorder = ui.PictureRecorder();
        final ui.Canvas canvas = ui.Canvas(recorder, drawRegion);
        canvas.drawImageNine(
          image,
          const ui.Rect.fromLTRB(50, 50, 100, 100),
          drawRegion,
          ui.Paint()
        );

        await drawPictureUsingCurrentRenderer(recorder.endRecording());

        await matchGoldenFile('${name}_canvas_drawImageNine.png', region: drawRegion);
      });

      test('image_shader_cubic_rotated', () async {
        final ui.Image image = await imageGenerator();

        final Float64List matrix = Matrix4.rotationZ(pi / 6).toFloat64();
        final ui.ImageShader shader = ui.ImageShader(
          image,
          ui.TileMode.repeated,
          ui.TileMode.repeated,
          matrix,
          filterQuality: ui.FilterQuality.high,
        );
        final ui.PictureRecorder recorder = ui.PictureRecorder();
        final ui.Canvas canvas = ui.Canvas(recorder, drawRegion);
        canvas.drawOval(
          const ui.Rect.fromLTRB(0, 50, 300, 250),
          ui.Paint()..shader = shader
        );

        await drawPictureUsingCurrentRenderer(recorder.endRecording());
        await matchGoldenFile('${name}_image_shader_cubic_rotated.png', region: drawRegion);
      });

      test('fragment_shader_sampler', () async {
        final ui.Image image = await imageGenerator();

        final ui.FragmentProgram program = await renderer.createFragmentProgram('glitch_shader');
        final ui.FragmentShader shader = program.fragmentShader();

        // Resolution
        shader.setFloat(0, 300);
        shader.setFloat(1, 300);

        // Time
        shader.setFloat(2, 2);

        // Image
        shader.setImageSampler(0, image);

        final ui.PictureRecorder recorder = ui.PictureRecorder();
        final ui.Canvas canvas = ui.Canvas(recorder, drawRegion);
        canvas.drawCircle(const ui.Offset(150, 150), 100, ui.Paint()..shader = shader);

        await drawPictureUsingCurrentRenderer(recorder.endRecording());

        await matchGoldenFile('${name}_fragment_shader_sampler.png', region: drawRegion);
      }, skip: isHtml); // HTML doesn't support fragment shaders

      test('toByteData_rgba', () async {
        final ui.Image image = await imageGenerator();

        final ByteData? rgbaData = await image.toByteData();
        expect(rgbaData, isNotNull);
        expect(rgbaData!.lengthInBytes, isNonZero);
      });

      test('toByteData_png', () async {
        final ui.Image image = await imageGenerator();

        final ByteData? pngData = await image.toByteData(format: ui.ImageByteFormat.png);
        expect(pngData, isNotNull);
        expect(pngData!.lengthInBytes, isNonZero);
      }, skip: isHtml); // https://github.com/flutter/flutter/issues/126611
    });
  }

  emitImageTests('picture_toImage', () {
    final ui.PictureRecorder recorder = ui.PictureRecorder();
    final ui.Canvas canvas = ui.Canvas(recorder, imageRegion);
    for (int y = 0; y < 15; y++) {
      for (int x = 0; x < 15; x++) {
        final ui.Offset center = ui.Offset(x * 10 + 5, y * 10 + 5);
        final ui.Color color = ui.Color.fromRGBO(
          (center.dx * 256 / 150).round(),
          (center.dy * 256 / 150).round(), 0, 1);
        canvas.drawCircle(center, 5, ui.Paint()..color = color);
      }
    }
    return recorder.endRecording().toImage(150, 150);
  });

  Uint8List generatePixelData(
    int width,
    int height,
    ui.Color Function(double, double) generator
  ) {
    final Uint8List data = Uint8List(width * height * 4);
    int outputIndex = 0;
    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        final ui.Color pixelColor = generator(
          (2.0 * x / width) - 1.0,
          (2.0 * y / height) - 1.0,
        );
        data[outputIndex++] = pixelColor.red;
        data[outputIndex++] = pixelColor.green;
        data[outputIndex++] = pixelColor.blue;
        data[outputIndex++] = pixelColor.alpha;
      }
    }
    return data;
  }

  emitImageTests('decodeImageFromPixels_unscaled', () {
    final Uint8List pixels = generatePixelData(150, 150, (double x, double y) {
      final double r = sqrt(x * x + y * y);
      final double theta = atan2(x, y);
      return ui.Color.fromRGBO(
        (255 * (sin(r * 10.0) + 1.0) / 2.0).round(),
        (255 * (sin(theta * 10.0) + 1.0) / 2.0).round(),
        0,
        1,
      );
    });
    final Completer<ui.Image> completer = Completer<ui.Image>();
    ui.decodeImageFromPixels(pixels, 150, 150, ui.PixelFormat.rgba8888, completer.complete);
    return completer.future;
  });

  // https://github.com/flutter/flutter/issues/126603
  if (!isHtml) {
    emitImageTests('decodeImageFromPixels_scaled', () {
      final Uint8List pixels = generatePixelData(50, 50, (double x, double y) {
        final double r = sqrt(x * x + y * y);
        final double theta = atan2(x, y);
        return ui.Color.fromRGBO(
          (255 * (sin(r * 10.0) + 1.0) / 2.0).round(),
          (255 * (sin(theta * 10.0) + 1.0) / 2.0).round(),
          0,
          1,
        );
      });
      final Completer<ui.Image> completer = Completer<ui.Image>();
      ui.decodeImageFromPixels(
        pixels,
        50,
        50,
        ui.PixelFormat.rgba8888,
        completer.complete,
        targetWidth: 150,
        targetHeight: 150,
      );
      return completer.future;
    });
  }

  emitImageTests('codec_uri', () async {
    final ui.Codec codec = await renderer.instantiateImageCodecFromUrl(
      Uri(path: '/test_images/mandrill_128.png')
    );
    expect(codec.frameCount, 1);

    final ui.FrameInfo info = await codec.getNextFrame();
    return info.image;
  });

  emitImageTests('codec_list_resized', () async {
    final ByteBuffer data = await httpFetchByteBuffer('/test_images/mandrill_128.png');
    final ui.Codec codec = await renderer.instantiateImageCodec(
      data.asUint8List(),
      targetWidth: 150,
      targetHeight: 150,
    );
    expect(codec.frameCount, 1);

    final ui.FrameInfo info = await codec.getNextFrame();
    return info.image;
  });
}
