// 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:math' as math;

import 'package:meta/meta.dart';

import 'logger.dart';
import 'platform.dart';
import 'terminal.dart';

// ignore_for_file: non_constant_identifier_names

const String fire = '🔥';
const int maxLineWidth = 84;

/// Encapsulates the help text construction and printing.
class CommandHelp {
  CommandHelp({
    @required Logger logger,
    @required AnsiTerminal terminal,
    @required Platform platform,
    @required OutputPreferences outputPreferences,
  }) : _logger = logger,
       _terminal = terminal,
       _platform = platform,
       _outputPreferences = outputPreferences;

  final Logger _logger;

  final AnsiTerminal _terminal;

  final Platform _platform;

  final OutputPreferences _outputPreferences;

  CommandHelpOption _L;
  CommandHelpOption get L => _L ??= _makeOption(
    'L',
    'Dump layer tree to the console.',
    'debugDumpLayerTree',
  );

  CommandHelpOption _P;
  CommandHelpOption get P => _P ??= _makeOption(
    'P',
    'Toggle performance overlay.',
    'WidgetsApp.showPerformanceOverlay',
  );

  CommandHelpOption _R;
  CommandHelpOption get R => _R ??= _makeOption(
    'R',
    'Hot restart.',
  );

  CommandHelpOption _S;
  CommandHelpOption get S => _S ??= _makeOption(
    'S',
    'Dump accessibility tree in traversal order.',
    'debugDumpSemantics',
  );

  CommandHelpOption _U;
  CommandHelpOption get U => _U ??= _makeOption(
    'U',
    'Dump accessibility tree in inverse hit test order.',
    'debugDumpSemantics',
  );

  CommandHelpOption _a;
  CommandHelpOption get a => _a ??= _makeOption(
    'a',
    'Toggle timeline events for all widget build methods.',
    'debugProfileWidgetBuilds',
  );

  CommandHelpOption _b;
  CommandHelpOption get b => _b ??= _makeOption(
    'b',
    'Toggle the platform brightness setting (dark and light mode).',
    'debugBrightnessOverride',
  );

  CommandHelpOption _c;
  CommandHelpOption get c => _c ??= _makeOption(
    'c',
    'Clear the screen',
  );

  CommandHelpOption _d;
  CommandHelpOption get d => _d ??= _makeOption(
    'd',
    'Detach (terminate "flutter run" but leave application running).',
  );

  CommandHelpOption _g;
  CommandHelpOption get g => _g ??= _makeOption(
    'g',
    'Run source code generators.'
  );

  CommandHelpOption _h;
  CommandHelpOption get h => _h ??= _makeOption(
    'h',
    'Repeat this help message.',
  );

  CommandHelpOption _i;
  CommandHelpOption get i => _i ??= _makeOption(
    'i',
    'Toggle widget inspector.',
    'WidgetsApp.showWidgetInspectorOverride',
  );

  CommandHelpOption _o;
  CommandHelpOption get o => _o ??= _makeOption(
    'o',
    'Simulate different operating systems.',
    'defaultTargetPlatform',
  );

  CommandHelpOption _p;
  CommandHelpOption get p => _p ??= _makeOption(
    'p',
    'Toggle the display of construction lines.',
    'debugPaintSizeEnabled',
  );

  CommandHelpOption _q;
  CommandHelpOption get q => _q ??= _makeOption(
    'q',
    'Quit (terminate the application on the device).',
  );

  CommandHelpOption _r;
  CommandHelpOption get r => _r ??= _makeOption(
    'r',
    'Hot reload. $fire$fire$fire',
  );

  CommandHelpOption _s;
  CommandHelpOption get s => _s ??= _makeOption(
    's',
    'Save a screenshot to flutter.png.',
  );

  CommandHelpOption _t;
  CommandHelpOption get t => _t ??= _makeOption(
    't',
    'Dump rendering tree to the console.',
    'debugDumpRenderTree',
  );

  CommandHelpOption _v;
  CommandHelpOption get v => _v ??= _makeOption(
    'v',
    'Launch DevTools.',
  );

  CommandHelpOption _w;
  CommandHelpOption get w => _w ??= _makeOption(
    'w',
    'Dump widget hierarchy to the console.',
    'debugDumpApp',
  );

  CommandHelpOption _z;
  CommandHelpOption get z => _z ??= _makeOption(
    'z',
    'Toggle elevation checker.',
  );

  CommandHelpOption _k;
  CommandHelpOption get k => _k ??= _makeOption(
    'k',
    'Toggle CanvasKit rendering.',
  );

  CommandHelpOption _M;
  CommandHelpOption get M => _M ??= _makeOption(
    'M',
    'Write SkSL shaders to a unique file in the project directory.',
  );

  CommandHelpOption _makeOption(String key, String description, [
    String inParenthesis = '',
  ]) {
    return CommandHelpOption(
      key,
      description,
      inParenthesis: inParenthesis,
      logger: _logger,
      terminal: _terminal,
      platform: _platform,
      outputPreferences: _outputPreferences,
    );
  }
}

/// Encapsulates printing help text for a single option.
class CommandHelpOption {
  CommandHelpOption(
    this.key,
    this.description, {
    this.inParenthesis = '',
    @required Logger logger,
    @required Terminal terminal,
    @required Platform platform,
    @required OutputPreferences outputPreferences,
  }) : _logger = logger,
       _terminal = terminal,
       _platform = platform,
       _outputPreferences = outputPreferences;

  final Logger _logger;

  final Terminal _terminal;

  final Platform _platform;

  final OutputPreferences _outputPreferences;

  /// The key associated with this command
  final String key;
  /// A description of what this command does
  final String description;
  /// Text shown in parenthesis to give the context
  final String inParenthesis;

  bool get _hasTextInParenthesis => inParenthesis != null && inParenthesis.isNotEmpty;

  int get _rawMessageLength => key.length + description.length;

  @override
  String toString() {
    final StringBuffer message = StringBuffer();
    message.writeAll(<String>[_terminal.bolden(key), description], ' ');
    if (!_hasTextInParenthesis) {
      return message.toString();
    }

    bool wrap = false;
    final int maxWidth = math.max(
      _outputPreferences.wrapColumn ?? 0,
      maxLineWidth,
    );
    final int adjustedMessageLength = _platform.stdoutSupportsAnsi
      ? _rawMessageLength + 1
      : message.length;
    int width = maxWidth - adjustedMessageLength;
    final String parentheticalText = '($inParenthesis)';
    if (width < parentheticalText.length) {
      width = maxWidth;
      wrap = true;
    }
    if (wrap) {
      message.write('\n');
    }
    // pad according to the raw text
    message.write(''.padLeft(width - parentheticalText.length));
    message.write(_terminal.color(parentheticalText, TerminalColor.grey));
    return message.toString();
  }

  void print() {
    _logger.printStatus(toString());
  }
}
