// 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 'dart:ui' as ui;

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

const Size _kTestViewSize = Size(800.0, 600.0);

class ScheduledFrameTrackingWindow extends TestWindow {
  ScheduledFrameTrackingWindow() : super(window: ui.window);

  int _scheduledFrameCount = 0;
  int get scheduledFrameCount => _scheduledFrameCount;

  void resetScheduledFrameCount() {
    _scheduledFrameCount = 0;
  }

  @override
  void scheduleFrame() {
    _scheduledFrameCount++;
    super.scheduleFrame();
  }
}

class ScheduledFrameTrackingBindings extends AutomatedTestWidgetsFlutterBinding {
  final ScheduledFrameTrackingWindow _window = ScheduledFrameTrackingWindow();

  @override
  ScheduledFrameTrackingWindow get window => _window;
}

class OffscreenRenderView extends RenderView {
  OffscreenRenderView() : super(
    configuration: const ViewConfiguration(size: _kTestViewSize),
    window: WidgetsBinding.instance!.window,
  );

  @override
  void compositeFrame() {
    // Don't draw to ui.window
  }
}

class OffscreenWidgetTree {
  OffscreenWidgetTree() {
    renderView.attach(pipelineOwner);
    renderView.prepareInitialFrame();
    pipelineOwner.requestVisualUpdate();
  }

  final RenderView renderView = OffscreenRenderView();
  final BuildOwner buildOwner = BuildOwner(focusManager: FocusManager());
  final PipelineOwner pipelineOwner = PipelineOwner();
  RenderObjectToWidgetElement<RenderBox>? root;

  void pumpWidget(Widget? app) {
    root = RenderObjectToWidgetAdapter<RenderBox>(
      container: renderView,
      debugShortDescription: '[root]',
      child: app,
    ).attachToRenderTree(buildOwner, root);
    pumpFrame();
  }

  void pumpFrame() {
    buildOwner.buildScope(root!);
    pipelineOwner.flushLayout();
    pipelineOwner.flushCompositingBits();
    pipelineOwner.flushPaint();
    renderView.compositeFrame();
    pipelineOwner.flushSemantics();
    buildOwner.finalizeTree();
  }

}

class Counter {
  int count = 0;
}

class Trigger {
  VoidCallback? callback;
  void fire() {
    callback?.call();
  }
}

class TriggerableWidget extends StatefulWidget {
  const TriggerableWidget({
    Key? key,
    required this.trigger,
    required this.counter,
  }) : super(key: key);

  final Trigger trigger;
  final Counter counter;

  @override
  TriggerableState createState() => TriggerableState();
}

class TriggerableState extends State<TriggerableWidget> {
  @override
  void initState() {
    super.initState();
    widget.trigger.callback = fire;
  }

  @override
  void didUpdateWidget(TriggerableWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    widget.trigger.callback = fire;
  }

  int _count = 0;
  void fire() {
    setState(() {
      _count++;
    });
  }

  @override
  Widget build(BuildContext context) {
    widget.counter.count++;
    return Text('Bang $_count!', textDirection: TextDirection.ltr);
  }
}

class TestFocusable extends StatefulWidget {
  const TestFocusable({
    Key? key,
    required this.focusNode,
    this.autofocus = true,
  }) : super(key: key);

  final bool autofocus;
  final FocusNode focusNode;

  @override
  TestFocusableState createState() => TestFocusableState();
}

class TestFocusableState extends State<TestFocusable> {
  bool _didAutofocus = false;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    if (!_didAutofocus && widget.autofocus) {
      _didAutofocus = true;
      FocusScope.of(context).autofocus(widget.focusNode);
    }
  }

  @override
  Widget build(BuildContext context) {
    return const Text('Test focus node', textDirection: TextDirection.ltr);
  }
}

void main() {
  // Override the bindings for this test suite so that we can track the number
  // of times a frame has been scheduled.
  ScheduledFrameTrackingBindings();

  testWidgets('RenderObjectToWidgetAdapter.attachToRenderTree does not schedule frame', (WidgetTester tester) async {
    expect(WidgetsBinding.instance, isA<ScheduledFrameTrackingBindings>());
    final ScheduledFrameTrackingWindow window = WidgetsBinding.instance!.window as ScheduledFrameTrackingWindow;
    window.resetScheduledFrameCount();
    expect(window.scheduledFrameCount, isZero);
    final OffscreenWidgetTree tree = OffscreenWidgetTree();
    tree.pumpWidget(const SizedBox.shrink());
    expect(window.scheduledFrameCount, isZero);
  });

  testWidgets('no crosstalk between widget build owners', (WidgetTester tester) async {
    final Trigger trigger1 = Trigger();
    final Counter counter1 = Counter();
    final Trigger trigger2 = Trigger();
    final Counter counter2 = Counter();
    final OffscreenWidgetTree tree = OffscreenWidgetTree();
    // Both counts should start at zero
    expect(counter1.count, equals(0));
    expect(counter2.count, equals(0));
    // Lay out the "onscreen" in the default test binding
    await tester.pumpWidget(TriggerableWidget(trigger: trigger1, counter: counter1));
    // Only the "onscreen" widget should have built
    expect(counter1.count, equals(1));
    expect(counter2.count, equals(0));
    // Lay out the "offscreen" in a separate tree
    tree.pumpWidget(TriggerableWidget(trigger: trigger2, counter: counter2));
    // Now both widgets should have built
    expect(counter1.count, equals(1));
    expect(counter2.count, equals(1));
    // Mark both as needing layout
    trigger1.fire();
    trigger2.fire();
    // Marking as needing layout shouldn't immediately build anything
    expect(counter1.count, equals(1));
    expect(counter2.count, equals(1));
    // Pump the "onscreen" layout
    await tester.pump();
    // Only the "onscreen" widget should have rebuilt
    expect(counter1.count, equals(2));
    expect(counter2.count, equals(1));
    // Pump the "offscreen" layout
    tree.pumpFrame();
    // Now both widgets should have rebuilt
    expect(counter1.count, equals(2));
    expect(counter2.count, equals(2));
    // Mark both as needing layout, again
    trigger1.fire();
    trigger2.fire();
    // Now pump the "offscreen" layout first
    tree.pumpFrame();
    // Only the "offscreen" widget should have rebuilt
    expect(counter1.count, equals(2));
    expect(counter2.count, equals(3));
    // Pump the "onscreen" layout
    await tester.pump();
    // Now both widgets should have rebuilt
    expect(counter1.count, equals(3));
    expect(counter2.count, equals(3));
  });

  testWidgets('no crosstalk between focus nodes', (WidgetTester tester) async {
    final OffscreenWidgetTree tree = OffscreenWidgetTree();
    final FocusNode onscreenFocus = FocusNode();
    final FocusNode offscreenFocus = FocusNode();
    await tester.pumpWidget(
      TestFocusable(
        focusNode: onscreenFocus,
      ),
    );
    tree.pumpWidget(
      TestFocusable(
        focusNode: offscreenFocus,
      ),
    );

    // Autofocus is delayed one frame.
    await tester.pump();
    tree.pumpFrame();

    expect(onscreenFocus.hasFocus, isTrue);
    expect(offscreenFocus.hasFocus, isTrue);
  });

  testWidgets('able to tear down offscreen tree', (WidgetTester tester) async {
    final OffscreenWidgetTree tree = OffscreenWidgetTree();
    final List<WidgetState> states = <WidgetState>[];
    tree.pumpWidget(SizedBox(child: TestStates(states: states)));
    expect(states, <WidgetState>[WidgetState.initialized]);
    expect(tree.renderView.child, isNotNull);
    tree.pumpWidget(null); // The root node should be allowed to have no child.
    expect(states, <WidgetState>[WidgetState.initialized, WidgetState.disposed]);
    expect(tree.renderView.child, isNull);
  });
}

enum WidgetState {
  initialized,
  disposed,
}

class TestStates extends StatefulWidget {
  const TestStates({Key? key, required this.states}) : super(key: key);

  final List<WidgetState> states;

  @override
  TestStatesState createState() => TestStatesState();
}

class TestStatesState extends State<TestStates> {
  @override
  void initState() {
    super.initState();
    widget.states.add(WidgetState.initialized);
  }

  @override
  void dispose() {
    widget.states.add(WidgetState.disposed);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) => Container();
}
