// Copyright 2014 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.

@Tags(<String>['reduced-test-set'])

import 'dart:math' as math show pi;

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

import '../widgets/semantics_tester.dart';

class MockCanvas extends Fake implements Canvas {
  late Path capturedPath;
  late Paint capturedPaint;

  @override
  void drawPath(Path path, Paint paint) {
    capturedPath = path;
    capturedPaint = paint;
  }

  late double capturedSx;
  late double capturedSy;

  @override
  void scale(double sx, [double? sy]) {
    capturedSx = sx;
    capturedSy = sy!;
    invocations.add(RecordedScale(sx, sy));
  }

  final List<RecordedCanvasCall> invocations = <RecordedCanvasCall>[];

  @override
  void rotate(double radians) {
    invocations.add(RecordedRotate(radians));
  }

  @override
  void translate(double dx, double dy) {
    invocations.add(RecordedTranslate(dx, dy));
  }
}

@immutable
abstract class RecordedCanvasCall {
  const RecordedCanvasCall();
}

class RecordedRotate extends RecordedCanvasCall {
  const RecordedRotate(this.radians);

  final double radians;

  @override
  bool operator ==(Object other) {
    return other is RecordedRotate && other.radians == radians;
  }

  @override
  int get hashCode => radians.hashCode;
}

class RecordedTranslate extends RecordedCanvasCall {
  const RecordedTranslate(this.dx, this.dy);

  final double dx;
  final double dy;

  @override
  bool operator ==(Object other) {
    return other is RecordedTranslate && other.dx == dx && other.dy == dy;
  }

  @override
  int get hashCode => Object.hash(dx, dy);
}

class RecordedScale extends RecordedCanvasCall {
  const RecordedScale(this.sx, this.sy);

  final double sx;
  final double sy;

  @override
  bool operator ==(Object other) {
    return other is RecordedScale && other.sx == sx && other.sy == sy;
  }

  @override
  int get hashCode => Object.hash(sx, sy);
}

void main() {
  testWidgets('IconTheme color', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
          ),
          child: AnimatedIcon(
            progress: AlwaysStoppedAnimation<double>(0.0),
            icon: AnimatedIcons.arrow_menu,
          ),
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
    final MockCanvas canvas = MockCanvas();
    customPaint.painter!.paint(canvas, const Size(48.0, 48.0));
    expect(canvas.capturedPaint, hasColor(0xFF666666));
  });

  testWidgets('IconTheme opacity', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
            opacity: 0.5,
          ),
          child: AnimatedIcon(
            progress: AlwaysStoppedAnimation<double>(0.0),
            icon: AnimatedIcons.arrow_menu,
          ),
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
    final MockCanvas canvas = MockCanvas();
    customPaint.painter!.paint(canvas, const Size(48.0, 48.0));
    expect(canvas.capturedPaint, hasColor(0x80666666));
  });

  testWidgets('color overrides IconTheme color', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
          ),
          child: AnimatedIcon(
            progress: AlwaysStoppedAnimation<double>(0.0),
            icon: AnimatedIcons.arrow_menu,
            color: Color(0xFF0000FF),
          ),
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
    final MockCanvas canvas = MockCanvas();
    customPaint.painter!.paint(canvas, const Size(48.0, 48.0));
    expect(canvas.capturedPaint, hasColor(0xFF0000FF));
  });

  testWidgets('IconTheme size', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
            size: 12.0,
          ),
          child: AnimatedIcon(
            progress: AlwaysStoppedAnimation<double>(0.0),
            icon: AnimatedIcons.arrow_menu,
          ),
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
    final MockCanvas canvas = MockCanvas();
    customPaint.painter!.paint(canvas, const Size(12.0, 12.0));
    // arrow_menu default size is 48x48 so we expect it to be scaled by 0.25.
    expect(canvas.capturedSx, 0.25);
    expect(canvas.capturedSy, 0.25);
  });

  testWidgets('size overridesIconTheme size', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
            size: 12.0,
          ),
          child: AnimatedIcon(
            progress: AlwaysStoppedAnimation<double>(0.0),
            icon: AnimatedIcons.arrow_menu,
            size: 96.0,
          ),
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
    final MockCanvas canvas = MockCanvas();
    customPaint.painter!.paint(canvas, const Size(12.0, 12.0));
    // arrow_menu default size is 48x48 so we expect it to be scaled by 2.
    expect(canvas.capturedSx, 2);
    expect(canvas.capturedSy, 2);
  });

  testWidgets('Semantic label', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);

    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: AnimatedIcon(
          progress: AlwaysStoppedAnimation<double>(0.0),
          icon: AnimatedIcons.arrow_menu,
          size: 96.0,
          semanticLabel: 'a label',
        ),
      ),
    );

    expect(semantics, includesNodeWith(label: 'a label'));

    semantics.dispose();
  });

  testWidgets('Inherited text direction rtl', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.rtl,
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
          ),
          child: RepaintBoundary(
            child: AnimatedIcon(
              progress: AlwaysStoppedAnimation<double>(0.0),
              icon: AnimatedIcons.arrow_menu,
            ),
          ),
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
    final MockCanvas canvas = MockCanvas();
    customPaint.painter!.paint(canvas, const Size(48.0, 48.0));
    expect(canvas.invocations, const <RecordedCanvasCall>[
      RecordedRotate(math.pi),
      RecordedTranslate(-48, -48),
      RecordedScale(0.5, 0.5),
    ]);
    await expectLater(find.byType(AnimatedIcon),
        matchesGoldenFile('animated_icons_test.icon.rtl.png'));
  });

  testWidgets('Inherited text direction ltr', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
          ),
          child: RepaintBoundary(
            child: AnimatedIcon(
              progress: AlwaysStoppedAnimation<double>(0.0),
              icon: AnimatedIcons.arrow_menu,
            ),
          ),
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
    final MockCanvas canvas = MockCanvas();
    customPaint.painter!.paint(canvas, const Size(48.0, 48.0));
    expect(canvas.invocations, const <RecordedCanvasCall>[
      RecordedScale(0.5, 0.5),
    ]);
    await expectLater(find.byType(AnimatedIcon),
        matchesGoldenFile('animated_icons_test.icon.ltr.png'));
  });

  testWidgets('Inherited text direction overridden', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
          ),
          child: AnimatedIcon(
            progress: AlwaysStoppedAnimation<double>(0.0),
            icon: AnimatedIcons.arrow_menu,
            textDirection: TextDirection.rtl,
          ),
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
    final MockCanvas canvas = MockCanvas();
    customPaint.painter!.paint(canvas, const Size(48.0, 48.0));
    expect(canvas.invocations, const <RecordedCanvasCall>[
      RecordedRotate(math.pi),
      RecordedTranslate(-48, -48),
      RecordedScale(0.5, 0.5),
    ]);
  });

  testWidgets('Direction has no effect on position of widget', (WidgetTester tester) async {
    const AnimatedIcon icon = AnimatedIcon(
      progress: AlwaysStoppedAnimation<double>(0.0),
      icon: AnimatedIcons.arrow_menu,
    );
    await tester.pumpWidget(
      const Directionality(textDirection: TextDirection.rtl, child: icon),
    );
    final Rect rtlRect = tester.getRect(find.byType(AnimatedIcon));
    await tester.pumpWidget(
      const Directionality(textDirection: TextDirection.ltr, child: icon),
    );
    final Rect ltrRect = tester.getRect(find.byType(AnimatedIcon));
    expect(rtlRect, ltrRect);
  });
}

PaintColorMatcher hasColor(int color) {
  return PaintColorMatcher(color);
}

class PaintColorMatcher extends Matcher {
  const PaintColorMatcher(this.expectedColor);

  final int expectedColor;

  @override
  Description describe(Description description) =>
    description.add('color was not $expectedColor');

  @override
  bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
    final Paint actualPaint = item as Paint;
    return actualPaint.color == Color(expectedColor);
  }
}
