// 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 'package:file/memory.dart';
import 'package:meta/meta.dart';

import '../convert.dart';
import 'error_handling_io.dart';
import 'file_system.dart';
import 'logger.dart';
import 'platform.dart';
import 'utils.dart';

/// A class to abstract configuration files.
class Config {
  /// Constructs a new [Config] object from a file called [name] in the
  /// current user's configuration directory as determined by the [Platform]
  /// and [FileSystem].
  ///
  /// The configuration directory defaults to $XDG_CONFIG_HOME on Linux and
  /// macOS, but falls back to the home directory if a file named
  /// `.flutter_$name` already exists there. On other platforms the
  /// configuration file will always be a file named `.flutter_$name` in the
  /// home directory.
  ///
  /// Uses some good default behaviours:
  /// - deletes the file if it's not valid JSON
  /// - reports an empty config in that case
  /// - logs and catches any exceptions
  factory Config(
    String name, {
    required FileSystem fileSystem,
    required Logger logger,
    required Platform platform
  }) {
    return Config._common(
      name,
      fileSystem: fileSystem,
      logger: logger,
      platform: platform
    );
  }

  /// Similar to the default config constructor, but with some different
  /// behaviours:
  /// - will not delete the config if it's not valid JSON
  /// - will log but also rethrow any exceptions while loading the JSON, so
  ///   you can actually detect whether something went wrong
  ///
  /// Useful if you want some more control.
  factory Config.managed(
    String name, {
    required FileSystem fileSystem,
    required Logger logger,
    required Platform platform
  }) {
    return Config._common(
      name,
      fileSystem: fileSystem,
      logger: logger,
      platform: platform,
      managed: true
    );
  }

  factory Config._common(
    String name, {
    required FileSystem fileSystem,
    required Logger logger,
    required Platform platform,
    bool managed = false
  }) {
    final String filePath = _configPath(platform, fileSystem, name);
    final File file = fileSystem.file(filePath);
    file.parent.createSync(recursive: true);
    return Config.createForTesting(file, logger, managed: managed);
  }

  /// Constructs a new [Config] object from a file called [name] in
  /// the given [Directory].
  ///
  /// Defaults to [BufferLogger], [MemoryFileSystem], and [name]=test.
  factory Config.test({
    String name = 'test',
    Directory? directory,
    Logger? logger,
    bool managed = false
  }) {
    directory ??= MemoryFileSystem.test().directory('/');
    return Config.createForTesting(
      directory.childFile('.${kConfigDir}_$name'),
      logger ?? BufferLogger.test(),
      managed: managed
    );
  }

  /// Test only access to the Config constructor.
  @visibleForTesting
  Config.createForTesting(File file, Logger logger, {bool managed = false}) : _file = file, _logger = logger {
    if (!_file.existsSync()) {
      return;
    }
    try {
      ErrorHandlingFileSystem.noExitOnFailure(() {
        _values = castStringKeyedMap(json.decode(_file.readAsStringSync())) ?? <String, Object>{};
      });
    } on FormatException {
      _logger
        ..printError('Failed to decode preferences in ${_file.path}.')
        ..printError(
          'You may need to reapply any previously saved configuration '
          'with the "flutter config" command.',
        );

      if (managed) {
        rethrow;
      } else {
        _file.deleteSync();
      }
    } on Exception catch (err) {
      _logger
        ..printError('Could not read preferences in ${file.path}.\n$err')
        ..printError(
          'You may need to resolve the error above and reapply any previously '
          'saved configuration with the "flutter config" command.',
        );

      if (managed) {
        rethrow;
      }
    }
  }

  /// The default directory name for Flutter's configs.

  /// Configs will be written to the user's config path. If there is already a
  /// file with the name `.${kConfigDir}_$name` in the user's home path, that
  /// file will be used instead.
  static const String kConfigDir = 'flutter';

  /// Environment variable specified in the XDG Base Directory
  /// [specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)
  /// to specify the user's configuration directory.
  static const String kXdgConfigHome = 'XDG_CONFIG_HOME';

  /// Fallback directory in the user's home directory if `XDG_CONFIG_HOME` is
  /// not defined.
  static const String kXdgConfigFallback = '.config';

  /// The default name for the Flutter config file.
  static const String kFlutterSettings = 'settings';

  final Logger _logger;

  File _file;

  String get configPath => _file.path;

  Map<String, dynamic> _values = <String, Object>{};

  Iterable<String> get keys => _values.keys;

  bool containsKey(String key) => _values.containsKey(key);

  Object? getValue(String key) => _values[key];

  void setValue(String key, Object value) {
    _values[key] = value;
    _flushValues();
  }

  void removeValue(String key) {
    _values.remove(key);
    _flushValues();
  }

  void _flushValues() {
    String json = const JsonEncoder.withIndent('  ').convert(_values);
    json = '$json\n';
    _file.writeAsStringSync(json);
  }

  // Reads the process environment to find the current user's home directory.
  //
  // If the searched environment variables are not set, '.' is returned instead.
  //
  // Note that this is different from FileSystemUtils.homeDirPath.
  static String _userHomePath(Platform platform) {
    final String envKey = platform.isWindows ? 'APPDATA' : 'HOME';
    return platform.environment[envKey] ?? '.';
  }

  static String _configPath(
      Platform platform, FileSystem fileSystem, String name) {
    final String homeDirFile =
        fileSystem.path.join(_userHomePath(platform), '.${kConfigDir}_$name');
    if (platform.isLinux || platform.isMacOS) {
      if (fileSystem.isFileSync(homeDirFile)) {
        return homeDirFile;
      }
      final String configDir = platform.environment[kXdgConfigHome] ??
          fileSystem.path.join(_userHomePath(platform), '.config', kConfigDir);
      return fileSystem.path.join(configDir, name);
    }
    return homeDirFile;
  }
}
