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

// @dart = 2.8

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

void main() {
  group('SafeArea', () {
    testWidgets('SafeArea - basic', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MediaQuery(
          data: MediaQueryData(padding: EdgeInsets.all(20.0)),
          child: SafeArea(
            left: false,
            child: Placeholder(),
          ),
        ),
      );
      expect(tester.getTopLeft(find.byType(Placeholder)), const Offset(0.0, 20.0));
      expect(tester.getBottomRight(find.byType(Placeholder)), const Offset(780.0, 580.0));
    });

    testWidgets('SafeArea - with minimums', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MediaQuery(
          data: MediaQueryData(padding: EdgeInsets.all(20.0)),
          child: SafeArea(
            top: false,
            minimum: EdgeInsets.fromLTRB(0.0, 10.0, 20.0, 30.0),
            child: Placeholder(),
          ),
        ),
      );
      expect(tester.getTopLeft(find.byType(Placeholder)), const Offset(20.0, 10.0));
      expect(tester.getBottomRight(find.byType(Placeholder)), const Offset(780.0, 570.0));
    });

    testWidgets('SafeArea - nested', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MediaQuery(
          data: MediaQueryData(padding: EdgeInsets.all(20.0)),
          child: SafeArea(
            top: false,
            child: SafeArea(
              right: false,
              child: Placeholder(),
            ),
          ),
        ),
      );
      expect(tester.getTopLeft(find.byType(Placeholder)), const Offset(20.0, 20.0));
      expect(tester.getBottomRight(find.byType(Placeholder)), const Offset(780.0, 580.0));
    });

    testWidgets('SafeArea - changing', (WidgetTester tester) async {
      const Widget child = SafeArea(
        bottom: false,
        child: SafeArea(
          left: false,
          bottom: false,
          child: Placeholder(),
        ),
      );
      await tester.pumpWidget(
        const MediaQuery(
          data: MediaQueryData(padding: EdgeInsets.all(20.0)),
          child: child,
        ),
      );
      expect(tester.getTopLeft(find.byType(Placeholder)), const Offset(20.0, 20.0));
      expect(tester.getBottomRight(find.byType(Placeholder)), const Offset(780.0, 600.0));
      await tester.pumpWidget(
        const MediaQuery(
          data: MediaQueryData(padding: EdgeInsets.only(
            left: 100.0,
            top: 30.0,
            right: 0.0,
            bottom: 40.0,
          )),
          child: child,
        ),
      );
      expect(tester.getTopLeft(find.byType(Placeholder)), const Offset(100.0, 30.0));
      expect(tester.getBottomRight(find.byType(Placeholder)), const Offset(800.0, 600.0));
    });

    testWidgets('SafeArea - properties', (WidgetTester tester) async {
      final SafeArea child = SafeArea(
        left: true,
        right: false,
        bottom: false,
        child: Container()
      );
      final DiagnosticPropertiesBuilder properties = DiagnosticPropertiesBuilder();
      child.debugFillProperties(properties);

      expect(properties.properties.any((DiagnosticsNode n) => n is FlagProperty && n.toString() == 'avoid left padding'), true);
      expect(properties.properties.any((DiagnosticsNode n) => n is FlagProperty && n.toString() == 'avoid right padding'), false);
      expect(properties.properties.any((DiagnosticsNode n) => n is FlagProperty && n.toString() == 'avoid top padding'), true);
      expect(properties.properties.any((DiagnosticsNode n) => n is FlagProperty && n.toString() == 'avoid bottom padding'), false);
    });

    group('SafeArea maintains bottom viewPadding when specified for consumed bottom padding', () {
      Widget boilerplate(Widget child) {
        return Localizations(
          locale: const Locale('en', 'us'),
          delegates: const <LocalizationsDelegate<dynamic>>[
            DefaultWidgetsLocalizations.delegate,
            DefaultMaterialLocalizations.delegate,
          ],
          child: Directionality(textDirection: TextDirection.ltr, child: child),
        );
      }

      testWidgets('SafeArea alone.', (WidgetTester tester) async {
        final Widget child = boilerplate(SafeArea(
          maintainBottomViewPadding: true,
          child: Column(
            children: const <Widget>[
              Expanded(child: Placeholder()),
            ],
          ),
        ));

        await tester.pumpWidget(
          MediaQuery(
            data: const MediaQueryData(
              padding: EdgeInsets.symmetric(vertical: 20.0),
              viewPadding: EdgeInsets.only(bottom: 20.0),
            ),
            child: child,
          ),
        );
        final Offset initialPoint = tester.getCenter(find.byType(Placeholder));
        // Consume bottom padding - as if by the keyboard opening
        await tester.pumpWidget(
          MediaQuery(
            data: const MediaQueryData(
              padding: EdgeInsets.only(top: 20.0),
              viewPadding: EdgeInsets.only(bottom: 20.0),
              viewInsets: EdgeInsets.only(bottom: 300.0),
            ),
            child: child,
          ),
        );
        final Offset finalPoint = tester.getCenter(find.byType(Placeholder));
        expect(initialPoint, finalPoint);
      });

      testWidgets('SafeArea with nested Scaffold', (WidgetTester tester) async {
        final Widget child = boilerplate(SafeArea(
          maintainBottomViewPadding: true,
          child: Scaffold(
            resizeToAvoidBottomInset: false,
            body: Column(
              children: const <Widget>[
                Expanded(child: Placeholder()),
              ],
            ),
          ),
        ));

        await tester.pumpWidget(
          MediaQuery(
            data: const MediaQueryData(
              padding: EdgeInsets.symmetric(vertical: 20.0),
              viewPadding: EdgeInsets.only(bottom: 20.0),
            ),
            child: child,
          ),
        );
        final Offset initialPoint = tester.getCenter(find.byType(Placeholder));
        // Consume bottom padding - as if by the keyboard opening
        await tester.pumpWidget(
          MediaQuery(
            data: const MediaQueryData(
              padding: EdgeInsets.only(top: 20.0),
              viewPadding: EdgeInsets.only(bottom: 20.0),
              viewInsets: EdgeInsets.only(bottom: 300.0),
            ),
            child: child,
          ),
        );
        final Offset finalPoint = tester.getCenter(find.byType(Placeholder));
        expect(initialPoint, finalPoint);
      });
    });
  });

  group('SliverSafeArea', () {
    Widget buildWidget(EdgeInsets mediaPadding, Widget sliver) {
      return MediaQuery(
        data: MediaQueryData(padding: mediaPadding),
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: Viewport(
            offset: ViewportOffset.fixed(0.0),
            axisDirection: AxisDirection.down,
            slivers: <Widget>[
              const SliverToBoxAdapter(child: SizedBox(width: 800.0, height: 100.0, child: Text('before'))),
              sliver,
              const SliverToBoxAdapter(child: SizedBox(width: 800.0, height: 100.0, child: Text('after'))),
            ],
          ),
        ),
      );
    }

    void verify(WidgetTester tester, List<Rect> expectedRects) {
      final List<Rect> testAnswers = tester.renderObjectList<RenderBox>(find.byType(SizedBox)).map<Rect>(
        (RenderBox target) {
          final Offset topLeft = target.localToGlobal(Offset.zero);
          final Offset bottomRight = target.localToGlobal(target.size.bottomRight(Offset.zero));
          return Rect.fromPoints(topLeft, bottomRight);
        }
      ).toList();
      expect(testAnswers, equals(expectedRects));
    }

    testWidgets('SliverSafeArea - basic', (WidgetTester tester) async {
      await tester.pumpWidget(
        buildWidget(
          const EdgeInsets.all(20.0),
          const SliverSafeArea(
            left: false,
            sliver: SliverToBoxAdapter(child: SizedBox(width: 800.0, height: 100.0, child: Text('padded'))),
          ),
        ),
      );
      verify(tester, <Rect>[
        const Rect.fromLTWH(0.0, 0.0, 800.0, 100.0),
        const Rect.fromLTWH(0.0, 120.0, 780.0, 100.0),
        const Rect.fromLTWH(0.0, 240.0, 800.0, 100.0),
      ]);
    });

    testWidgets('SliverSafeArea - basic', (WidgetTester tester) async {
      await tester.pumpWidget(
        buildWidget(
          const EdgeInsets.all(20.0),
          const SliverSafeArea(
            top: false,
            minimum: EdgeInsets.fromLTRB(0.0, 10.0, 20.0, 30.0),
            sliver: SliverToBoxAdapter(child: SizedBox(width: 800.0, height: 100.0, child: Text('padded'))),
          ),
        ),
      );
      verify(tester, <Rect>[
        const Rect.fromLTWH(0.0, 0.0, 800.0, 100.0),
        const Rect.fromLTWH(20.0, 110.0, 760.0, 100.0),
        const Rect.fromLTWH(0.0, 240.0, 800.0, 100.0),
      ]);
    });

    testWidgets('SliverSafeArea - nested', (WidgetTester tester) async {
      await tester.pumpWidget(
        buildWidget(
          const EdgeInsets.all(20.0),
          const SliverSafeArea(
            top: false,
            sliver: SliverSafeArea(
              right: false,
              sliver: SliverToBoxAdapter(child: SizedBox(width: 800.0, height: 100.0, child: Text('padded'))),
            ),
          ),
        ),
      );
      verify(tester, <Rect>[
        const Rect.fromLTWH(0.0, 0.0, 800.0, 100.0),
        const Rect.fromLTWH(20.0, 120.0, 760.0, 100.0),
        const Rect.fromLTWH(0.0, 240.0, 800.0, 100.0),
      ]);
    });

    testWidgets('SliverSafeArea - changing', (WidgetTester tester) async {
      const Widget sliver = SliverSafeArea(
        bottom: false,
        sliver: SliverSafeArea(
          left: false,
          bottom: false,
          sliver: SliverToBoxAdapter(child: SizedBox(width: 800.0, height: 100.0, child: Text('padded'))),
        ),
      );
      await tester.pumpWidget(
        buildWidget(
          const EdgeInsets.all(20.0),
          sliver,
        ),
      );
      verify(tester, <Rect>[
        const Rect.fromLTWH(0.0, 0.0, 800.0, 100.0),
        const Rect.fromLTWH(20.0, 120.0, 760.0, 100.0),
        const Rect.fromLTWH(0.0, 220.0, 800.0, 100.0),
      ]);

      await tester.pumpWidget(
        buildWidget(
          const EdgeInsets.only(
            left: 100.0,
            top: 30.0,
            right: 0.0,
            bottom: 40.0,
          ),
          sliver,
        ),
      );
      verify(tester, <Rect>[
        const Rect.fromLTWH(0.0, 0.0, 800.0, 100.0),
        const Rect.fromLTWH(100.0, 130.0, 700.0, 100.0),
        const Rect.fromLTWH(0.0, 230.0, 800.0, 100.0),
      ]);
    });
  });

  testWidgets('SliverSafeArea - properties', (WidgetTester tester) async {
    const SliverSafeArea child = SliverSafeArea(
      left: true,
      right: false,
      bottom: false,
      sliver: SliverToBoxAdapter(child: SizedBox(width: 800.0, height: 100.0, child: Text('padded'))),
    );
    final DiagnosticPropertiesBuilder properties = DiagnosticPropertiesBuilder();
    child.debugFillProperties(properties);

    expect(properties.properties.any((DiagnosticsNode n) => n is FlagProperty && n.toString() == 'avoid left padding'), true);
    expect(properties.properties.any((DiagnosticsNode n) => n is FlagProperty && n.toString() == 'avoid right padding'), false);
    expect(properties.properties.any((DiagnosticsNode n) => n is FlagProperty && n.toString() == 'avoid top padding'), true);
    expect(properties.properties.any((DiagnosticsNode n) => n is FlagProperty && n.toString() == 'avoid bottom padding'), false);
  });
}
