// 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:async';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:flutter_driver/driver_extension.dart';

void main() {
  enableFlutterDriverExtension();
  debugPrint('Application starting...');
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State createState() => MyAppState();
}

const MethodChannel channel = MethodChannel('texture');

enum FrameState { initial, slow, afterSlow, fast, afterFast }

class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  int _widgetBuilds = 0;
  FrameState _state = FrameState.initial;
  String _summary = '';
  IconData? _icon;
  double _flutterFrameRate = 0;

  Future<void> _summarizeStats() async {
    final double? framesProduced = await channel.invokeMethod('getProducedFrameRate');
    final double? framesConsumed = await channel.invokeMethod('getConsumedFrameRate');
    _summary = '''
Produced: ${framesProduced?.toStringAsFixed(1)}fps
Consumed: ${framesConsumed?.toStringAsFixed(1)}fps
Widget builds: $_widgetBuilds''';
  }

  Future<void> _nextState() async {
    switch (_state) {
      case FrameState.initial:
        debugPrint('Starting .5x speed test...');
        _widgetBuilds = 0;
        _summary = 'Producing texture frames at .5x speed...';
        _state = FrameState.slow;
        _icon = Icons.stop;
        channel.invokeMethod<void>('start', _flutterFrameRate ~/ 2);
        break;
      case FrameState.slow:
        debugPrint('Stopping .5x speed test...');
        await channel.invokeMethod<void>('stop');
        await _summarizeStats();
        _icon = Icons.fast_forward;
        _state = FrameState.afterSlow;
        break;
      case FrameState.afterSlow:
        debugPrint('Starting 2x speed test...');
        _widgetBuilds = 0;
        _summary = 'Producing texture frames at 2x speed...';
        _state = FrameState.fast;
        _icon = Icons.stop;
        channel.invokeMethod<void>('start', (_flutterFrameRate * 2).toInt());
        break;
      case FrameState.fast:
        debugPrint('Stopping 2x speed test...');
        await channel.invokeMethod<void>('stop');
        await _summarizeStats();
        _state = FrameState.afterFast;
        _icon = Icons.replay;
        break;
      case FrameState.afterFast:
        debugPrint('Test complete.');
        _summary = 'Press play to start again';
        _state = FrameState.initial;
        _icon = Icons.play_arrow;
        break;
    }
    setState(() {});
  }

  @override
  void initState() {
    super.initState();
    _calibrate();
  }

  static const int calibrationTickCount = 600;

  /// Measures Flutter's frame rate.
  Future<void> _calibrate() async {
    debugPrint('Awaiting calm (3 second pause)...');
    await Future<void>.delayed(const Duration(milliseconds: 3000));
    debugPrint('Calibrating...');
    late DateTime startTime;
    int tickCount = 0;
    Ticker? ticker;
    ticker = createTicker((Duration time) {
      tickCount += 1;
      if (tickCount == calibrationTickCount) { // about 10 seconds
        final Duration elapsed = DateTime.now().difference(startTime);
        ticker?.stop();
        ticker?.dispose();
        setState(() {
          _flutterFrameRate = tickCount * 1000 / elapsed.inMilliseconds;
          debugPrint('Calibrated: frame rate ${_flutterFrameRate.toStringAsFixed(1)}fps.');
          _summary = '''
Flutter frame rate is ${_flutterFrameRate.toStringAsFixed(1)}fps.
Press play to produce texture frames.''';
          _icon = Icons.play_arrow;
          _state = FrameState.initial;
        });
      } else {
        if ((tickCount % (calibrationTickCount ~/ 20)) == 0) {
          debugPrint('Calibrating... ${(100.0 * tickCount / calibrationTickCount).floor()}%');
        }
      }
    });
    ticker.start();
    startTime = DateTime.now();
    setState(() {
      _summary = 'Calibrating...';
      _icon = null;
    });
  }

  @override
  Widget build(BuildContext context) {
    _widgetBuilds += 1;
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const SizedBox(
                width: 300.0,
                height: 200.0,
                child: Texture(textureId: 0),
              ),
              Container(
                width: 300.0,
                height: 60.0,
                color: Colors.grey,
                child: Center(
                  child: Text(
                    _summary,
                    key: const ValueKey<String>('summary'),
                  ),
                ),
              ),
            ],
          ),
        ),
        floatingActionButton: _icon == null ? null : FloatingActionButton(
          key: const ValueKey<String>('fab'),
          onPressed: _nextState,
          child: Icon(_icon),
        ),
      ),
    );
  }
}
