// 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 '../test_utils.dart';
import 'project.dart';

class HotReloadProject extends Project {
  @override
  final String pubspec = '''
  name: test
  environment:
    sdk: ">=2.12.0-0 <3.0.0"

  dependencies:
    flutter:
      sdk: flutter
  ''';

  @override
  final String main = r'''
  import 'package:flutter/material.dart';
  import 'package:flutter/scheduler.dart';
  import 'package:flutter/services.dart';
  import 'package:flutter/widgets.dart';
  import 'package:flutter/foundation.dart';

  void main() async {
    WidgetsFlutterBinding.ensureInitialized();
    final ByteData message = const StringCodec().encodeMessage('AppLifecycleState.resumed')!;
    await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { });
    // See https://github.com/flutter/flutter/issues/86202
    if (kIsWeb) {
      while (true) {
        runApp(MyApp());
        await Future.delayed(const Duration(seconds: 1));
      }
    } else {
     runApp(MyApp());
    }
  }

  int count = 1;

  class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      // This method gets called each time we hot reload, during reassemble.

      // Do not remove the next line, it's uncommented by a test to verify that
      // hot reloading worked:
      // printHotReloadWorked();

      print('((((TICK $count))))');
      // tick 1 = startup warmup frame
      // tick 2 = hot reload warmup reassemble frame
      // after that there's a post-hot-reload frame scheduled by the tool that
      // doesn't trigger this to rebuild, but does trigger the first callback
      // below, then that callback schedules another frame on which we do the
      // breakpoint.
      // tick 3 = second hot reload warmup reassemble frame (pre breakpoint)
      if (count == 2) {
        SchedulerBinding.instance!.scheduleFrameCallback((Duration timestamp) {
          SchedulerBinding.instance!.scheduleFrameCallback((Duration timestamp) {
            print('breakpoint line'); // SCHEDULED BREAKPOINT
          });
        });
      }
      count += 1;

      return MaterialApp( // BUILD BREAKPOINT
        title: 'Flutter Demo',
        home: Container(),
      );
    }
  }

  void printHotReloadWorked() {
    // The call to this function is uncommented by a test to verify that hot
    // reloading worked.
    print('(((((RELOAD WORKED)))))');
  }
  ''';

  Uri get scheduledBreakpointUri => mainDart;
  int get scheduledBreakpointLine => lineContaining(main, '// SCHEDULED BREAKPOINT');

  Uri get buildBreakpointUri => mainDart;
  int get buildBreakpointLine => lineContaining(main, '// BUILD BREAKPOINT');

  void uncommentHotReloadPrint() {
    final String newMainContents = main.replaceAll(
      '// printHotReloadWorked();',
      'printHotReloadWorked();',
    );
    writeFile(
      fileSystem.path.join(dir.path, 'lib', 'main.dart'),
      newMainContents,
      writeFutureModifiedDate: true,
    );
  }
}
