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

import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;

import 'constants.dart';

/// The location of the Flutter root directory, based on the known location of
/// this script.
final Directory flutterRoot = Directory(
  path.dirname(Platform.script.toFilePath()),
).parent.parent.parent.parent;
String get dataRoot => testDataRoot ?? _dataRoot;
String _dataRoot = path.join(flutterRoot.path, 'dev', 'tools', 'gen_keycodes', 'data');

/// Allows overriding of the [dataRoot] for testing purposes.
@visibleForTesting
String? testDataRoot;

/// Converts `FOO_BAR` to `FooBar`.
String shoutingToUpperCamel(String shouting) {
  final initialLetter = RegExp(r'(?:_|^)([^_])([^_]*)');
  final String snake = shouting.toLowerCase();
  final String result = snake.replaceAllMapped(initialLetter, (Match match) {
    return match.group(1)!.toUpperCase() + match.group(2)!.toLowerCase();
  });
  return result;
}

/// Converts 'FooBar' to 'fooBar'.
///
/// 'TVFoo' should be convert to 'tvFoo'.
/// 'KeyX' should be convert to 'keyX'.
String upperCamelToLowerCamel(String upperCamel) {
  final initialGroup = RegExp(r'^([A-Z]([A-Z]*|[^A-Z]*))([A-Z]([^A-Z]|$)|$)');
  return upperCamel.replaceFirstMapped(initialGroup, (Match match) {
    return match.group(1)!.toLowerCase() + (match.group(3) ?? '');
  });
}

/// Converts 'fooBar' to 'FooBar'.
String lowerCamelToUpperCamel(String lowerCamel) {
  return lowerCamel.substring(0, 1).toUpperCase() + lowerCamel.substring(1);
}

/// A list of Dart reserved words.
///
/// Since these are Dart reserved words, we can't use them as-is for enum names.
const List<String> kDartReservedWords = <String>[
  'abstract',
  'as',
  'assert',
  'async',
  'await',
  'break',
  'case',
  'catch',
  'class',
  'const',
  'continue',
  'covariant',
  'default',
  'deferred',
  'do',
  'dynamic',
  'else',
  'enum',
  'export',
  'extends',
  'external',
  'factory',
  'false',
  'final',
  'finally',
  'for',
  'Function',
  'get',
  'hide',
  'if',
  'implements',
  'import',
  'in',
  'interface',
  'is',
  'library',
  'mixin',
  'new',
  'null',
  'on',
  'operator',
  'part',
  'rethrow',
  'return',
  'set',
  'show',
  'static',
  'super',
  'switch',
  'sync',
  'this',
  'throw',
  'true',
  'try',
  'typedef',
  'var',
  'void',
  'while',
  'with',
  'yield',
];

/// Converts an integer into a hex string with the given number of digits.
String toHex(int? value, {int digits = 8}) {
  if (value == null) {
    return 'null';
  }
  return '0x${value.toRadixString(16).padLeft(digits, '0')}';
}

/// Parses an integer from a hex string.
int getHex(String input) {
  return int.parse(input, radix: 16);
}

/// Given an [input] string, wraps the text at 80 characters and prepends each
/// line with the [prefix] string. Use for generated comments.
String wrapString(String input, {required String prefix}) {
  final int wrapWidth = 80 - prefix.length;
  final result = StringBuffer();
  final List<String> words = input.split(RegExp(r'\s+'));
  String currentLine = words.removeAt(0);
  for (final word in words) {
    if ((currentLine.length + word.length) < wrapWidth) {
      currentLine += ' $word';
    } else {
      result.writeln('$prefix$currentLine');
      currentLine = word;
    }
  }
  if (currentLine.isNotEmpty) {
    result.writeln('$prefix$currentLine');
  }
  return result.toString();
}

/// Run `fn` with each corresponding element from list1 and list2.
///
/// If `list1` has a different length from `list2`, the execution is aborted
/// after printing an error.
///
/// An null list is considered a list with length 0.
void zipStrict<T1, T2>(Iterable<T1> list1, Iterable<T2> list2, void Function(T1, T2) fn) {
  assert(list1.length == list2.length);
  final Iterator<T1> it1 = list1.iterator;
  final Iterator<T2> it2 = list2.iterator;
  while (it1.moveNext()) {
    it2.moveNext();
    fn(it1.current, it2.current);
  }
}

/// Read a Map<String, String> out of its string representation in JSON.
Map<String, String> parseMapOfString(String jsonString) {
  return (json.decode(jsonString) as Map<String, dynamic>).cast<String, String>();
}

/// Read a Map<String, List<String>> out of its string representation in JSON.
Map<String, List<String>> parseMapOfListOfString(String jsonString) {
  final Map<String, List<dynamic>> dynamicMap = (json.decode(jsonString) as Map<String, dynamic>)
      .cast<String, List<dynamic>>();
  return dynamicMap.map<String, List<String>>((String key, List<dynamic> value) {
    return MapEntry<String, List<String>>(key, value.cast<String>());
  });
}

Map<String, List<String?>> parseMapOfListOfNullableString(String jsonString) {
  final Map<String, List<dynamic>> dynamicMap = (json.decode(jsonString) as Map<String, dynamic>)
      .cast<String, List<dynamic>>();
  return dynamicMap.map<String, List<String?>>((String key, List<dynamic> value) {
    return MapEntry<String, List<String?>>(key, value.cast<String?>());
  });
}

Map<String, bool> parseMapOfBool(String jsonString) {
  return (json.decode(jsonString) as Map<String, dynamic>).cast<String, bool>();
}

/// Reverse the map of { fromValue -> list of toValue } to { toValue -> fromValue } and return.
Map<String, String> reverseMapOfListOfString(
  Map<String, List<String>> inMap,
  void Function(String fromValue, String newToValue) onDuplicate,
) {
  final result = <String, String>{};
  inMap.forEach((String fromValue, List<String> toValues) {
    for (final toValue in toValues) {
      if (result.containsKey(toValue)) {
        onDuplicate(fromValue, toValue);
        continue;
      }
      result[toValue] = fromValue;
    }
  });
  return result;
}

/// Remove entries whose value `isEmpty` or is null, and return the map.
///
/// Will modify the input map.
Map<String, dynamic> removeEmptyValues(Map<String, dynamic> map) {
  return map..removeWhere(
    (String key, dynamic value) => switch (value) {
      null => true,
      Map<String, dynamic>() => removeEmptyValues(value).isEmpty,
      Iterable<dynamic>() => value.isEmpty,
      _ => false,
    },
  );
}

void addNameValue(List<String> names, List<int> values, String name, int value) {
  final int foundIndex = values.indexOf(value);
  if (foundIndex == -1) {
    names.add(name);
    values.add(value);
  } else {
    if (!RegExp(r'(^|, )abc1($|, )').hasMatch(name)) {
      names[foundIndex] = '${names[foundIndex]}, $name';
    }
  }
}

enum DeduplicateBehavior {
  // Warn the duplicate entry.
  kWarn,

  // Skip the latter duplicate entry.
  kSkip,

  // Keep all duplicate entries.
  kKeep,
}

/// The information for a line used by [OutputLines].
class OutputLine<T extends Comparable<Object>> {
  OutputLine(this.key, String value) : values = <String>[value];

  final T key;
  final List<String> values;
}

/// A utility class to build join a number of lines in a sorted order.
///
/// Use [add] to add a line and associate it with an index. Use [sortedJoin] to
/// get the joined string of these lines joined sorting them in the order of the
/// index.
class OutputLines<T extends Comparable<Object>> {
  OutputLines(this.mapName, {this.behavior = DeduplicateBehavior.kWarn});

  /// What to do if there are entries with the same key.
  final DeduplicateBehavior behavior;

  /// The name for this map.
  ///
  /// Used in warning messages.
  final String mapName;

  final Map<T, OutputLine<T>> lines = <T, OutputLine<T>>{};

  void add(T key, String line) {
    final OutputLine<T>? existing = lines[key];
    if (existing != null) {
      switch (behavior) {
        case DeduplicateBehavior.kWarn:
          print(
            'Warn: Request to add $key to map "$mapName" as:\n    $line\n  but it already exists as:\n    ${existing.values[0]}',
          );
          return;
        case DeduplicateBehavior.kSkip:
          return;
        case DeduplicateBehavior.kKeep:
          existing.values.add(line);
          return;
      }
    }
    lines[key] = OutputLine<T>(key, line);
  }

  String join() {
    return lines.values.map((OutputLine<T> line) => line.values.join('\n')).join('\n');
  }

  String sortedJoin() {
    return (lines.values.toList()
          ..sort((OutputLine<T> a, OutputLine<T> b) => a.key.compareTo(b.key)))
        .map((OutputLine<T> line) => line.values.join('\n'))
        .join('\n');
  }
}

int toPlane(int value, int plane) {
  return (value & kValueMask.value) + (plane & kPlaneMask.value);
}

int getPlane(int value) {
  return value & kPlaneMask.value;
}
