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

import 'package:flutter/foundation.dart' show FlutterError;
import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart';

class TestCanvas implements Canvas {
  final List<Invocation> invocations = <Invocation>[];

  @override
  void noSuchMethod(Invocation invocation) {
    invocations.add(invocation);
  }
}

void main() {
  test('Border.uniform constructor', () {
    const BorderSide side = BorderSide();
    const Border border = Border.fromBorderSide(side);
    expect(border.left, same(side));
    expect(border.top, same(side));
    expect(border.right, same(side));
    expect(border.bottom, same(side));
  });

  test('Border.symmetric constructor', () {
    const BorderSide side1 = BorderSide(color: Color(0xFFFFFFFF));
    const BorderSide side2 = BorderSide();
    const Border border = Border.symmetric(vertical: side1, horizontal: side2);
    expect(border.left, same(side1));
    expect(border.top, same(side2));
    expect(border.right, same(side1));
    expect(border.bottom, same(side2));
  });

  test('Border.merge', () {
    const BorderSide magenta3 = BorderSide(color: Color(0xFFFF00FF), width: 3.0);
    const BorderSide magenta6 = BorderSide(color: Color(0xFFFF00FF), width: 6.0);
    const BorderSide yellow2 = BorderSide(color: Color(0xFFFFFF00), width: 2.0);
    const BorderSide yellowNone0 = BorderSide(color: Color(0xFFFFFF00), width: 0.0, style: BorderStyle.none);
    expect(
      Border.merge(
        const Border(top: yellow2),
        const Border(right: magenta3),
      ),
      const Border(top: yellow2, right: magenta3),
    );
    expect(
      Border.merge(
        const Border(bottom: magenta3),
        const Border(bottom: magenta3),
      ),
      const Border(bottom: magenta6),
    );
    expect(
      Border.merge(
        const Border(left: magenta3, right: yellowNone0),
        const Border(right: yellow2),
      ),
      const Border(left: magenta3, right: yellow2),
    );
    expect(
      Border.merge(const Border(), const Border()),
      const Border(),
    );
    expect(
      () => Border.merge(
        const Border(left: magenta3),
        const Border(left: yellow2),
      ),
      throwsAssertionError,
    );
  });

  test('Border.add', () {
    const BorderSide magenta3 = BorderSide(color: Color(0xFFFF00FF), width: 3.0);
    const BorderSide magenta6 = BorderSide(color: Color(0xFFFF00FF), width: 6.0);
    const BorderSide yellow2 = BorderSide(color: Color(0xFFFFFF00), width: 2.0);
    const BorderSide yellowNone0 = BorderSide(color: Color(0xFFFFFF00), width: 0.0, style: BorderStyle.none);
    expect(
      const Border(top: yellow2) + const Border(right: magenta3),
      const Border(top: yellow2, right: magenta3),
    );
    expect(
      const Border(bottom: magenta3) + const Border(bottom: magenta3),
      const Border(bottom: magenta6),
    );
    expect(
      const Border(left: magenta3, right: yellowNone0) + const Border(right: yellow2),
      const Border(left: magenta3, right: yellow2),
    );
    expect(
      const Border() + const Border(),
      const Border(),
    );
    expect(
      const Border(left: magenta3) + const Border(left: yellow2),
      isNot(isA<Border>()), // see shape_border_test.dart for better tests of this case
    );
    const Border b3 = Border(top: magenta3);
    const Border b6 = Border(top: magenta6);
    expect(b3 + b3, b6);
    const Border b0 = Border(top: yellowNone0);
    const Border bZ = Border();
    expect(b0 + b0, bZ);
    expect(bZ + bZ, bZ);
    expect(b0 + bZ, bZ);
    expect(bZ + b0, bZ);
  });

  test('Border.scale', () {
    const BorderSide magenta3 = BorderSide(color: Color(0xFFFF00FF), width: 3.0);
    const BorderSide magenta6 = BorderSide(color: Color(0xFFFF00FF), width: 6.0);
    const BorderSide yellow2 = BorderSide(color: Color(0xFFFFFF00), width: 2.0);
    const BorderSide yellowNone0 = BorderSide(color: Color(0xFFFFFF00), width: 0.0, style: BorderStyle.none);
    const Border b3 = Border(left: magenta3);
    const Border b6 = Border(left: magenta6);
    expect(b3.scale(2.0), b6);
    const Border bY0 = Border(top: yellowNone0);
    expect(bY0.scale(3.0), bY0);
    const Border bY2 = Border(top: yellow2);
    expect(bY2.scale(0.0), bY0);
  });

  test('Border.dimensions', () {
    expect(
      const Border(
        left: BorderSide(width: 2.0),
        top: BorderSide(width: 3.0),
        bottom: BorderSide(width: 5.0),
        right: BorderSide(width: 7.0),
      ).dimensions,
      const EdgeInsets.fromLTRB(2.0, 3.0, 7.0, 5.0),
    );
  });

  test('Border.isUniform', () {
    expect(
      const Border(
        left: BorderSide(width: 3.0),
        top: BorderSide(width: 3.0),
        right: BorderSide(width: 3.0),
        bottom: BorderSide(width: 3.1),
      ).isUniform,
      false,
    );
    expect(
      const Border(
        left: BorderSide(width: 3.0),
        top: BorderSide(width: 3.0),
        right: BorderSide(width: 3.0),
        bottom: BorderSide(width: 3.0),
      ).isUniform,
      true,
    );
    expect(
      const Border(
        left: BorderSide(color: Color(0xFFFFFFFE)),
        top: BorderSide(color: Color(0xFFFFFFFF)),
        right: BorderSide(color: Color(0xFFFFFFFF)),
        bottom: BorderSide(color: Color(0xFFFFFFFF)),
      ).isUniform,
      false,
    );
    expect(
      const Border(
        left: BorderSide(color: Color(0xFFFFFFFF)),
        top: BorderSide(color: Color(0xFFFFFFFF)),
        right: BorderSide(color: Color(0xFFFFFFFF)),
        bottom: BorderSide(color: Color(0xFFFFFFFF)),
      ).isUniform,
      true,
    );
    expect(
      const Border(
        left: BorderSide(style: BorderStyle.none),
        top: BorderSide(style: BorderStyle.none),
        right: BorderSide(style: BorderStyle.none),
        bottom: BorderSide(width: 0.0),
      ).isUniform,
      false,
    );
    expect(
      const Border(
        left: BorderSide(style: BorderStyle.none),
        top: BorderSide(style: BorderStyle.none),
        right: BorderSide(style: BorderStyle.none),
        bottom: BorderSide(width: 0.0),
      ).isUniform,
      false,
    );
    expect(
      const Border(
        left: BorderSide(style: BorderStyle.none),
        top: BorderSide(style: BorderStyle.none),
        right: BorderSide(style: BorderStyle.none),
      ).isUniform,
      false,
    );
    expect(
      const Border(
        left: BorderSide(),
        top: BorderSide(strokeAlign: BorderSide.strokeAlignCenter),
        right: BorderSide(strokeAlign: BorderSide.strokeAlignOutside),
      ).isUniform,
      false,
    );
    expect(
      const Border().isUniform,
      true,
    );
    expect(
      const Border().isUniform,
      true,
    );
  });

  test('Border.lerp', () {
    const Border visualWithTop10 = Border(top: BorderSide(width: 10.0));
    const Border atMinus100 = Border(left: BorderSide(width: 0.0), right: BorderSide(width: 300.0));
    const Border at0 = Border(left: BorderSide(width: 100.0), right: BorderSide(width: 200.0));
    const Border at25 = Border(left: BorderSide(width: 125.0), right: BorderSide(width: 175.0));
    const Border at75 = Border(left: BorderSide(width: 175.0), right: BorderSide(width: 125.0));
    const Border at100 = Border(left: BorderSide(width: 200.0), right: BorderSide(width: 100.0));
    const Border at200 = Border(left: BorderSide(width: 300.0), right: BorderSide(width: 0.0));

    expect(Border.lerp(null, null, -1.0), null);
    expect(Border.lerp(visualWithTop10, null, -1.0), const Border(top: BorderSide(width: 20.0)));
    expect(Border.lerp(null, visualWithTop10, -1.0), const Border());
    expect(Border.lerp(at0, at100, -1.0), atMinus100);

    expect(Border.lerp(null, null, 0.0), null);
    expect(Border.lerp(visualWithTop10, null, 0.0), const Border(top: BorderSide(width: 10.0)));
    expect(Border.lerp(null, visualWithTop10, 0.0), const Border());
    expect(Border.lerp(at0, at100, 0.0), at0);

    expect(Border.lerp(null, null, 0.25), null);
    expect(Border.lerp(visualWithTop10, null, 0.25), const Border(top: BorderSide(width: 7.5)));
    expect(Border.lerp(null, visualWithTop10, 0.25), const Border(top: BorderSide(width: 2.5)));
    expect(Border.lerp(at0, at100, 0.25), at25);

    expect(Border.lerp(null, null, 0.75), null);
    expect(Border.lerp(visualWithTop10, null, 0.75), const Border(top: BorderSide(width: 2.5)));
    expect(Border.lerp(null, visualWithTop10, 0.75), const Border(top: BorderSide(width: 7.5)));
    expect(Border.lerp(at0, at100, 0.75), at75);

    expect(Border.lerp(null, null, 1.0), null);
    expect(Border.lerp(visualWithTop10, null, 1.0), const Border());
    expect(Border.lerp(null, visualWithTop10, 1.0), const Border(top: BorderSide(width: 10.0)));
    expect(Border.lerp(at0, at100, 1.0), at100);

    expect(Border.lerp(null, null, 2.0), null);
    expect(Border.lerp(visualWithTop10, null, 2.0), const Border());
    expect(Border.lerp(null, visualWithTop10, 2.0), const Border(top: BorderSide(width: 20.0)));
    expect(Border.lerp(at0, at100, 2.0), at200);
  });

  test('Border - throws correct exception with strokeAlign', () {
    late FlutterError error;
    try {
      final TestCanvas canvas = TestCanvas();
      // Border.all supports all StrokeAlign values.
      // Border() supports [BorderSide.strokeAlignInside] only.
      const Border(
        left: BorderSide(strokeAlign: BorderSide.strokeAlignCenter),
        right: BorderSide(strokeAlign: BorderSide.strokeAlignOutside),
      ).paint(canvas, const Rect.fromLTWH(10.0, 20.0, 30.0, 40.0));
    } on FlutterError catch (e) {
      error = e;
    }
    expect(error, isNotNull);
    expect(error.diagnostics.length, 1);
    expect(
      error.diagnostics[0].toStringDeep(),
      'A Border can only draw strokeAlign different than\nBorderSide.strokeAlignInside on uniform borders.\n',
    );
  });

  test('Border.dimension', () {
    final Border insideBorder = Border.all(width: 10);
    expect(insideBorder.dimensions, const EdgeInsets.all(10));

    final Border centerBorder = Border.all(width: 10, strokeAlign: BorderSide.strokeAlignCenter);
    expect(centerBorder.dimensions, const EdgeInsets.all(5));

    final Border outsideBorder = Border.all(width: 10, strokeAlign: BorderSide.strokeAlignOutside);
    expect(outsideBorder.dimensions, EdgeInsets.zero);

    const BorderSide insideSide = BorderSide(width: 10);
    const BorderDirectional insideBorderDirectional = BorderDirectional(top: insideSide, bottom: insideSide, start: insideSide, end: insideSide);
    expect(insideBorderDirectional.dimensions, const EdgeInsetsDirectional.all(10));

    const BorderSide centerSide = BorderSide(width: 10, strokeAlign: BorderSide.strokeAlignCenter);
    const BorderDirectional centerBorderDirectional = BorderDirectional(top: centerSide, bottom: centerSide, start: centerSide, end: centerSide);
    expect(centerBorderDirectional.dimensions, const EdgeInsetsDirectional.all(5));

    const BorderSide outsideSide = BorderSide(width: 10, strokeAlign: BorderSide.strokeAlignOutside);
    const BorderDirectional outsideBorderDirectional = BorderDirectional(top: outsideSide, bottom: outsideSide, start: outsideSide, end: outsideSide);
    expect(outsideBorderDirectional.dimensions, EdgeInsetsDirectional.zero);
  });
}
