// Copyright 2019 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:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

import 'package:cocoon_service/protos.dart' show Commit, Task;

import '../agent_dashboard_page.dart';
import '../logic/qualified_task.dart';
import '../state/build.dart';
import 'luci_task_attempt_summary.dart';
import 'progress_button.dart';
import 'task_attempt_summary.dart';
import 'task_box.dart';

/// Displays the information from [Task] and allows interacting with a [Task].
///
/// This is intended to be inserted in an [OverlayEntry] as it requires
/// [closeCallback] that will remove the widget from the tree.
class TaskOverlayEntry extends StatelessWidget {
  const TaskOverlayEntry({
    Key key,
    @required this.position,
    @required this.task,
    @required this.showSnackBarCallback,
    @required this.closeCallback,
    @required this.buildState,
    @required this.commit,
  })  : assert(position != null),
        assert(buildState != null),
        assert(task != null),
        assert(showSnackBarCallback != null),
        assert(closeCallback != null),
        super(key: key);

  /// The global position where to show the task overlay.
  final Offset position;

  /// The [Task] to display in the overlay.
  final Task task;

  final ShowSnackBarCallback showSnackBarCallback;

  /// This callback removes the parent overlay from the widget tree.
  ///
  /// On a click that is outside the area of the overlay (the rest of the screen),
  /// this callback is called closing the overlay.
  final VoidCallback closeCallback;

  /// A reference to the [BuildState] for performing operations on this [Task].
  final BuildState buildState;

  /// [Commit] for cirrus tasks to show log.
  final Commit commit;

  @override
  Widget build(BuildContext context) {
    // If this is ever positioned not at the top-left of the viewport, then
    // we should make sure to convert the position to the Overlay's coordinate
    // space otherwise it'll be misaligned.
    return Stack(
      children: <Widget>[
        // This is a focus container to emphasize the cell that this
        // [Overlay] is currently showing information from.
        Positioned(
          top: position.dy,
          left: position.dx,
          width: TaskBox.cellSize,
          height: TaskBox.cellSize,
          child: Container(
            decoration: BoxDecoration(
              border: Border.all(color: Colors.black, width: 4.0),
              color: Colors.white70,
            ),
          ),
        ),
        // This is the area a user can click (the rest of the screen) to close the overlay.
        GestureDetector(
          onTap: closeCallback,
          behavior: HitTestBehavior.opaque,
          child: const SizedBox.expand(),
        ),
        Positioned(
          // Move this overlay to be where the parent is
          // TODO(ianh): This will go past the edge of the page if it's near the right margin;
          // we should do something like positionDependentBox.
          top: position.dy + TaskBox.cellSize / 2.0,
          left: position.dx + TaskBox.cellSize / 2.0,
          child: TaskOverlayContents(
            showSnackBarCallback: showSnackBarCallback,
            buildState: buildState,
            task: task,
            commit: commit,
            closeCallback: closeCallback,
          ),
        ),
      ],
    );
  }
}

/// Displays the information from [Task] and allows interacting with a [Task].
///
/// This is intended to be inserted in [TaskOverlayEntry].
///
/// Offers the functionality of opening the log for this [Task] and rerunning
/// this [Task] through the build system.
class TaskOverlayContents extends StatelessWidget {
  const TaskOverlayContents({
    Key key,
    @required this.showSnackBarCallback,
    @required this.buildState,
    @required this.task,
    @required this.closeCallback,
    this.commit,
  })  : assert(showSnackBarCallback != null),
        assert(buildState != null),
        assert(task != null),
        super(key: key);

  final ShowSnackBarCallback showSnackBarCallback;

  /// A reference to the [BuildState] for performing operations on this [Task].
  final BuildState buildState;

  /// The [Task] to display in the overlay
  final Task task;

  /// [Commit] for cirrus tasks to show log.
  final Commit commit;

  /// This callback removes the parent overlay from the widget tree.
  ///
  /// This is used in this scope to close this overlay on redirection to view
  /// the agent for this task in the agent dashboard.
  final void Function() closeCallback;

  @visibleForTesting
  static const String rerunErrorMessage = 'Failed to rerun task.';
  @visibleForTesting
  static const String rerunSuccessMessage = 'Devicelab is rerunning the task. This can take a minute to propagate.';
  @visibleForTesting
  static const Duration rerunSnackBarDuration = Duration(seconds: 15);
  @visibleForTesting
  static const String downloadLogErrorMessage = 'Failed to download task log.';
  @visibleForTesting
  static const Duration downloadLogSnackBarDuration = Duration(seconds: 15);

  /// A lookup table to define the [Icon] for this task, based on
  /// the values returned by [TaskBox.effectiveTaskStatus].
  static const Map<String, Icon> statusIcon = <String, Icon>{
    TaskBox.statusFailed: Icon(Icons.clear, color: Colors.red, size: 32),
    TaskBox.statusNew: Icon(Icons.new_releases, color: Colors.blue, size: 32),
    TaskBox.statusInProgress: Icon(Icons.autorenew, color: Colors.blue, size: 32),
    TaskBox.statusSucceeded: Icon(Icons.check_circle, color: Colors.green, size: 32),
    TaskBox.statusSucceededButFlaky: Icon(Icons.check_circle_outline, size: 32),
    TaskBox.statusUnderperformed: Icon(Icons.new_releases, color: Colors.orange, size: 32),
    TaskBox.statusUnderperformedInProgress: Icon(Icons.autorenew, color: Colors.orange, size: 32),
  };

  @override
  Widget build(BuildContext context) {
    final DateTime createTime = DateTime.fromMillisecondsSinceEpoch(task.createTimestamp.toInt());
    final DateTime startTime = DateTime.fromMillisecondsSinceEpoch(task.startTimestamp.toInt());
    final DateTime endTime = DateTime.fromMillisecondsSinceEpoch(task.endTimestamp.toInt());

    final Duration queueDuration = startTime.difference(createTime);
    final Duration runDuration = endTime.difference(startTime);

    final String taskStatus = TaskBox.effectiveTaskStatus(task);

    return Card(
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
        child: IntrinsicWidth(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.symmetric(vertical: 8.0),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Tooltip(
                      message: taskStatus,
                      child: Padding(
                        padding: const EdgeInsets.only(left: 8.0, top: 10.0, right: 12.0),
                        child: statusIcon[taskStatus],
                      ),
                    ),
                    Expanded(
                      child: ListBody(
                        children: <Widget>[
                          SelectableText(
                            task.name,
                            style: Theme.of(context).textTheme.bodyText1,
                          ),
                          if (QualifiedTask.fromTask(task).isDevicelab)
                            Text(
                              'Attempts: ${task.attempts}\n'
                              'Run time: ${runDuration.inMinutes} minutes\n'
                              'Queue time: ${queueDuration.inSeconds} seconds\n'
                              'Flaky: ${task.isFlaky}',
                              style: Theme.of(context).textTheme.bodyText2,
                            )
                          else
                            Text(
                              'Task was run outside of devicelab',
                              style: Theme.of(context).textTheme.bodyText2,
                            ),
                          if (QualifiedTask.fromTask(task).isDevicelab) TaskAttemptSummary(task: task),
                          if (QualifiedTask.fromTask(task).isLuci) LuciTaskAttemptSummary(task: task),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: <Widget>[
                  if (QualifiedTask.fromTask(task).isDevicelab)
                    RaisedButton(
                      child: Text.rich(
                        TextSpan(
                          text: 'SHOW ',
                          children: <TextSpan>[
                            TextSpan(
                              text: task.reservedForAgentId,
                              style: const TextStyle(fontStyle: FontStyle.italic),
                            ),
                          ],
                        ),
                      ),
                      onPressed: () {
                        // Close the current overlay
                        closeCallback();

                        // Open the agent dashboard
                        Navigator.pushNamed(
                          context,
                          AgentDashboardPage.routeName,
                          arguments: task.reservedForAgentId,
                        );
                      },
                    ),
                  Padding(
                    padding: const EdgeInsets.only(left: 8.0),
                    child: ProgressButton(
                      child: const Text('DOWNLOAD ALL LOGS'),
                      onPressed: _viewLog,
                    ),
                  ),
                  if (QualifiedTask.fromTask(task).isDevicelab)
                    Padding(
                      padding: const EdgeInsets.only(left: 8.0),
                      child: ProgressButton(
                        child: const Text('RERUN'),
                        onPressed: _rerunTask,
                      ),
                    ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _rerunTask() async {
    final bool success = await buildState.rerunTask(task);
    final Text snackBarText = success ? const Text(rerunSuccessMessage) : const Text(rerunErrorMessage);
    showSnackBarCallback(
      SnackBar(
        content: snackBarText,
        duration: rerunSnackBarDuration,
      ),
    );
  }

  /// If [task] is in the devicelab, download the log. Otherwise, open the
  /// url closest to where the log will be.
  ///
  /// If a devicelab log fails to download, show an error snack bar.
  Future<void> _viewLog() async {
    if (QualifiedTask.fromTask(task).isDevicelab) {
      final bool success = await buildState.downloadLog(task, commit);

      if (!success) {
        /// Only show [SnackBar] on failure since the user's device will
        /// indicate a download has been made.
        showSnackBarCallback(
          const SnackBar(
            content: Text(downloadLogErrorMessage),
            duration: rerunSnackBarDuration,
          ),
        );
      }

      return;
    }

    /// Tasks outside of devicelab have public logs that we just redirect to.
    launch(logUrl(task, commit: commit));
  }
}
