// 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:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';

VoidCallback? originalSemanticsListener;

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  // Disconnects semantics listener for testing purposes.
  originalSemanticsListener = WidgetsBinding.instance.platformDispatcher.onSemanticsEnabledChanged;
  RendererBinding.instance.platformDispatcher.onSemanticsEnabledChanged = null;
  RendererBinding.instance.setSemanticsEnabled(false);
  // If the test passes, LifeCycleSpy will rewire the semantics listener back.
  runApp(const LifeCycleSpy());
}

/// A Test widget that spies on app life cycle changes.
///
/// It will collect the AppLifecycleState sequence during its lifetime, and it
/// will rewire semantics harness if the sequence it receives matches the
/// expected list.
///
/// Rewiring semantics is a signal to native IOS test that the test has passed.
class LifeCycleSpy extends StatefulWidget {
  const LifeCycleSpy({super.key});

  @override
  State<LifeCycleSpy> createState() => _LifeCycleSpyState();
}

class _LifeCycleSpyState extends State<LifeCycleSpy> with WidgetsBindingObserver {
  final List<AppLifecycleState> _expectedLifeCycleSequence = <AppLifecycleState>[
    AppLifecycleState.detached,
    AppLifecycleState.inactive,
    AppLifecycleState.resumed,
  ];
  List<AppLifecycleState?>? _actualLifeCycleSequence;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    _actualLifeCycleSequence =  <AppLifecycleState?>[
      ServicesBinding.instance.lifecycleState,
    ];
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    setState(() {
      _actualLifeCycleSequence = List<AppLifecycleState>.from(_actualLifeCycleSequence!);
      _actualLifeCycleSequence?.add(state);
    });
  }

  @override
  Widget build(BuildContext context) {
    if (const ListEquality<AppLifecycleState?>().equals(_actualLifeCycleSequence, _expectedLifeCycleSequence)) {
      // Rewires the semantics harness if test passes.
      RendererBinding.instance.setSemanticsEnabled(true);
      RendererBinding.instance.platformDispatcher.onSemanticsEnabledChanged = originalSemanticsListener;
    }
    return const MaterialApp(
      title: 'Flutter View',
      home: Text('test'),
    );
  }
}
