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

// This file is run as part of a reduced test set in CI on Mac and Windows
// machines.
@Tags(<String>['reduced-test-set'])
library;

import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:platform/platform.dart';

void main() {
  testWidgets('IconData object test', (WidgetTester tester) async {
    expect(Icons.account_balance, isNot(equals(Icons.account_box)));
    expect(Icons.account_balance.hashCode, isNot(equals(Icons.account_box.hashCode)));
    expect(Icons.account_balance, hasOneLineDescription);
  });

  testWidgets('Icons specify the material font', (WidgetTester tester) async {
    expect(Icons.clear.fontFamily, 'MaterialIcons');
    expect(Icons.search.fontFamily, 'MaterialIcons');
  });

  testWidgets('Certain icons (and their variants) match text direction', (
    WidgetTester tester,
  ) async {
    expect(Icons.arrow_back.matchTextDirection, true);
    expect(Icons.arrow_back_rounded.matchTextDirection, true);
    expect(Icons.arrow_back_outlined.matchTextDirection, true);
    expect(Icons.arrow_back_sharp.matchTextDirection, true);

    expect(Icons.access_time.matchTextDirection, false);
    expect(Icons.access_time_rounded.matchTextDirection, false);
    expect(Icons.access_time_outlined.matchTextDirection, false);
    expect(Icons.access_time_sharp.matchTextDirection, false);
  });

  testWidgets(
    'Adaptive icons are correct on cupertino platforms',
    (WidgetTester tester) async {
      expect(Icons.adaptive.arrow_back, Icons.arrow_back_ios);
      expect(Icons.adaptive.arrow_back_outlined, Icons.arrow_back_ios_outlined);
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{
      TargetPlatform.iOS,
      TargetPlatform.macOS,
    }),
  );

  testWidgets(
    'Adaptive icons are correct on non-cupertino platforms',
    (WidgetTester tester) async {
      expect(Icons.adaptive.arrow_back, Icons.arrow_back);
      expect(Icons.adaptive.arrow_back_outlined, Icons.arrow_back_outlined);
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{
      TargetPlatform.android,
      TargetPlatform.fuchsia,
      TargetPlatform.windows,
      TargetPlatform.linux,
    }),
  );

  testWidgets('A sample of icons look as expected', (WidgetTester tester) async {
    await _loadIconFont();

    await tester.pumpWidget(
      const MaterialApp(
        home: IconTheme(
          data: IconThemeData(size: 200),
          child: Wrap(
            children: <Icon>[
              Icon(Icons.ten_k),
              Icon(Icons.ac_unit),
              Icon(Icons.local_taxi),
              Icon(Icons.local_taxi_outlined),
              Icon(Icons.local_taxi_rounded),
              Icon(Icons.local_taxi_sharp),
              Icon(Icons.zoom_out_sharp),
            ],
          ),
        ),
      ),
    );

    await expectLater(find.byType(Wrap), matchesGoldenFile('test.icons.sample.png'));
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/39998

  // Regression test for https://github.com/flutter/flutter/issues/95886
  testWidgets('Another sample of icons look as expected', (WidgetTester tester) async {
    await _loadIconFont();

    await tester.pumpWidget(
      const MaterialApp(
        home: IconTheme(
          data: IconThemeData(size: 200),
          child: Wrap(
            children: <Icon>[
              Icon(Icons.water_drop),
              Icon(Icons.water_drop_outlined),
              Icon(Icons.water_drop_rounded),
              Icon(Icons.water_drop_sharp),
            ],
          ),
        ),
      ),
    );

    await expectLater(find.byType(Wrap), matchesGoldenFile('test.icons.sample2.png'));
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/39998

  testWidgets('Another sample of icons look as expected', (WidgetTester tester) async {
    await _loadIconFont();

    await tester.pumpWidget(
      const MaterialApp(
        home: IconTheme(
          data: IconThemeData(size: 200),
          child: Wrap(
            children: <Icon>[
              Icon(Icons.electric_bolt),
              Icon(Icons.electric_bolt_outlined),
              Icon(Icons.electric_bolt_rounded),
              Icon(Icons.electric_bolt_sharp),
            ],
          ),
        ),
      ),
    );

    await expectLater(find.byType(Wrap), matchesGoldenFile('test.icons.sample3.png'));
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/39998

  // Regression test for https://github.com/flutter/flutter/issues/103202.
  testWidgets('Another sample of icons look as expected', (WidgetTester tester) async {
    await _loadIconFont();

    await tester.pumpWidget(
      const MaterialApp(
        home: IconTheme(
          data: IconThemeData(size: 200),
          child: Wrap(
            children: <Icon>[
              Icon(Icons.repeat_on),
              Icon(Icons.repeat_on_outlined),
              Icon(Icons.repeat_on_rounded),
              Icon(Icons.repeat_on_sharp),
            ],
          ),
        ),
      ),
    );

    await expectLater(find.byType(Wrap), matchesGoldenFile('test.icons.sample4.png'));
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/39998
}

// Loads the cached material icon font.
// Only necessary for golden tests. Relies on the tool updating cached assets before
// running tests.
Future<void> _loadIconFont() async {
  const FileSystem fs = LocalFileSystem();
  const Platform platform = LocalPlatform();
  final Directory flutterRoot = fs.directory(platform.environment['FLUTTER_ROOT']);

  final File iconFont = flutterRoot.childFile(
    fs.path.join('bin', 'cache', 'artifacts', 'material_fonts', 'MaterialIcons-Regular.otf'),
  );

  final bytes = Future<ByteData>.value(iconFont.readAsBytesSync().buffer.asByteData());

  await (FontLoader('MaterialIcons')..addFont(bytes)).load();
}
