// 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:convert';
import 'dart:isolate';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

typedef OnProgressListener = void Function(double completed, double total);
typedef OnResultListener = void Function(String result);

// An encapsulation of a large amount of synchronous processing.
//
// The choice of JSON parsing here is meant as an example that might surface
// in real-world applications.
class Calculator {
  Calculator({ required this.onProgressListener, required this.onResultListener, String? data })
    : assert(onProgressListener != null),
      assert(onResultListener != null),
      // In order to keep the example files smaller, we "cheat" a little and
      // replicate our small json string into a 10,000-element array.
      _data = _replicateJson(data, 10000);

  final OnProgressListener onProgressListener;
  final OnResultListener onResultListener;
  final String _data;
  // This example assumes that the number of objects to parse is known in
  // advance. In a real-world situation, this might not be true; in that case,
  // the app might choose to display an indeterminate progress indicator.
  static const int _NUM_ITEMS = 110000;
  static const int _NOTIFY_INTERVAL = 1000;

  // Run the computation associated with this Calculator.
  void run() {
    int i = 0;
    final JsonDecoder decoder = JsonDecoder(
      (dynamic key, dynamic value) {
        if (key is int && i++ % _NOTIFY_INTERVAL == 0)
          onProgressListener(i.toDouble(), _NUM_ITEMS.toDouble());
        return value;
      },
    );
    try {
      final List<dynamic> result = decoder.convert(_data) as List<dynamic>;
      final int n = result.length;
      onResultListener('Decoded $n results');
    } catch (e, stack) {
      print('Invalid JSON file: $e');
      print(stack);
    }
  }

  static String _replicateJson(String? data, int count) {
    final StringBuffer buffer = StringBuffer()..write('[');
    for (int i = 0; i < count; i++) {
      buffer.write(data);
      if (i < count - 1)
        buffer.write(',');
    }
    buffer.write(']');
    return buffer.toString();
  }
}

// The current state of the calculation.
enum CalculationState {
  idle,
  loading,
  calculating
}

// Structured message to initialize the spawned isolate.
class CalculationMessage {
  CalculationMessage(this.data, this.sendPort);
  String data;
  SendPort sendPort;
}

// A manager for the connection to a spawned isolate.
//
// Isolates communicate with each other via ReceivePorts and SendPorts.
// This class manages these ports and maintains state related to the
// progress of the background computation.
class CalculationManager {
  CalculationManager({ required this.onProgressListener, required this.onResultListener })
    : assert(onProgressListener != null),
      assert(onResultListener != null),
      _receivePort = ReceivePort() {
    _receivePort.listen(_handleMessage);
  }

  CalculationState _state = CalculationState.idle;
  CalculationState get state => _state;
  bool get isRunning => _state != CalculationState.idle;

  double _completed = 0.0;
  double _total = 1.0;

  final OnProgressListener onProgressListener;
  final OnResultListener onResultListener;

  // Start the background computation.
  //
  // Does nothing if the computation is already running.
  void start() {
    if (!isRunning) {
      _state = CalculationState.loading;
      _runCalculation();
    }
  }

  // Stop the background computation.
  //
  // Kills the isolate immediately, if spawned. Does nothing if the
  // computation is not running.
  void stop() {
    if (isRunning) {
      _state = CalculationState.idle;
      if (_isolate != null) {
        _isolate!.kill(priority: Isolate.immediate);
        _isolate = null;
        _completed = 0.0;
        _total = 1.0;
      }
    }
  }

  final ReceivePort _receivePort;
  Isolate? _isolate;

  void _runCalculation() {
    // Load the JSON string. This is done in the main isolate because spawned
    // isolates do not have access to the root bundle. However, the loading
    // process is asynchronous, so the UI will not block while the file is
    // loaded.
    rootBundle.loadString('services/data.json').then<void>((String data) {
      if (isRunning) {
        final CalculationMessage message = CalculationMessage(data, _receivePort.sendPort);
        // Spawn an isolate to JSON-parse the file contents. The JSON parsing
        // is synchronous, so if done in the main isolate, the UI would block.
        Isolate.spawn<CalculationMessage>(_calculate, message).then<void>((Isolate isolate) {
          if (!isRunning) {
            isolate.kill(priority: Isolate.immediate);
          } else {
            _state = CalculationState.calculating;
            _isolate = isolate;
          }
        });
      }
    });
  }

  void _handleMessage(dynamic message) {
    if (message is List<double>) {
      _completed = message[0];
      _total = message[1];
      onProgressListener(_completed, _total);
    } else if (message is String) {
      _completed = 0.0;
      _total = 1.0;
      _isolate = null;
      _state = CalculationState.idle;
      onResultListener(message);
    }
  }

  // Main entry point for the spawned isolate.
  //
  // This entry point must be static, and its (single) argument must match
  // the message passed in Isolate.spawn above. Typically, some part of the
  // message will contain a SendPort so that the spawned isolate can
  // communicate back to the main isolate.
  //
  // Static and global variables are initialized anew in the spawned isolate,
  // in a separate memory space.
  static void _calculate(CalculationMessage message) {
    final SendPort sender = message.sendPort;
    final Calculator calculator = Calculator(
      onProgressListener: (double completed, double total) {
        sender.send(<double>[ completed, total ]);
      },
      onResultListener: sender.send,
      data: message.data,
    );
    calculator.run();
  }
}

// Main app widget.
//
// The app shows a simple UI that allows control of the background computation,
// as well as an animation to illustrate that the UI does not block while this
// computation is performed.
//
// This is a StatefulWidget in order to hold the CalculationManager and
// the AnimationController for the running animation.
class IsolateExampleWidget extends StatefulWidget {
  const IsolateExampleWidget({Key? key}) : super(key: key);

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

// Main application state.
class IsolateExampleState extends State<StatefulWidget> with SingleTickerProviderStateMixin {

  String _status = 'Idle';
  String _label = 'Start';
  String _result = ' ';
  double _progress = 0.0;
  late final AnimationController _animation = AnimationController(
    duration: const Duration(milliseconds: 3600),
    vsync: this,
  )..repeat();
  late final CalculationManager _calculationManager = CalculationManager(
    onProgressListener: _handleProgressUpdate,
    onResultListener: _handleResult,
  );

  @override
  void dispose() {
    _animation.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          RotationTransition(
            turns: _animation,
            child: Container(
              width: 120.0,
              height: 120.0,
              color: const Color(0xFF882222),
            ),
          ),
          Opacity(
            opacity: _calculationManager.isRunning ? 1.0 : 0.0,
            child: CircularProgressIndicator(
              value: _progress,
            ),
          ),
          Text(_status),
          Center(
            child: ElevatedButton(
              onPressed: _handleButtonPressed,
              child: Text(_label),
            ),
          ),
          Text(_result),
        ],
      ),
    );
  }

  void _handleProgressUpdate(double completed, double total) {
    _updateState(' ', completed / total);
  }

  void _handleResult(String result) {
    _updateState(result, 0.0);
  }

  void _handleButtonPressed() {
    if (_calculationManager.isRunning)
      _calculationManager.stop();
    else
      _calculationManager.start();
    _updateState(' ', 0.0);
  }

  String _getStatus(CalculationState state) {
    switch (state) {
      case CalculationState.loading:
        return 'Loading...';
      case CalculationState.calculating:
        return 'In Progress';
      case CalculationState.idle:
      default:
        return 'Idle';
    }
  }

  void _updateState(String result, double progress) {
    setState(() {
      _result = result;
      _progress = progress;
      _label = _calculationManager.isRunning ? 'Stop' : 'Start';
      _status = _getStatus(_calculationManager.state);
    });
  }
}

void main() {
  runApp(const MaterialApp(home: IsolateExampleWidget()));
}
