// Copyright (c) 2025, the Dart project authors.  Please see the AUTHORS file
// for details. 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:io' show Platform;

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

import '../cli_util.dart';

/// The standard system paths for a Dart tool.
///
/// These paths respects the following directory standards:
///
/// - On Linux, the [XDG Base Directory
///   Specification](https://specifications.freedesktop.org/basedir-spec/latest/).
/// - On MacOS, the
///   [Library](https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html)
///   directory.
/// - On Windows, `%APPDATA%` and `%LOCALAPPDATA%`.
///
/// Note that [cacheHome], [configHome], [dataHome], [runtimeHome], and
/// [stateHome] may be overlapping or nested.
///
/// Note that the directories won't be created, the methods merely return the
/// recommended locations.
final class BaseDirectories {
  /// The name of the Dart tool.
  ///
  /// The name is used to provide a subdirectory inside the base directories.
  ///
  /// This should be a valid directory name on every operating system. The name
  /// is typically camel-cased. For example: `"MyApp"`.
  final String tool;

  /// The environment variables to use to determine the base directories.
  ///
  /// Defaults to [Platform.environment].
  final Map<String, String> _environment;

  /// Constructs a [BaseDirectories] instance for the given [tool] name.
  ///
  /// The [environment] map, if provided, is used to determine the base
  /// directories. If omitted, it defaults to using [Platform.environment].
  BaseDirectories(
    this.tool, {
    Map<String, String>? environment,
  }) : _environment = environment ?? Platform.environment;

  /// Path of the directory where the tool will place its caches.
  ///
  /// The cache may be purged by the operating system or user at any time.
  /// Applications should be able to reconstruct any data stored here. If [tool]
  /// cannot handle data being purged, use [runtimeHome] or [dataHome] instead.
  ///
  /// This is a location appropriate for storing non-essential files that may be
  /// removed at any point. For example: intermediate compilation artifacts.
  ///
  /// The directory location depends on the current [Platform.operatingSystem]:
  /// - on **Windows**:
  ///   - `%LOCALAPPDATA%\<tool>`
  /// - on **Mac OS**:
  ///   - `$HOME/Library/Caches/<tool>`
  /// - on **Linux**:
  ///   - `$XDG_CACHE_HOME/<tool>` if `$XDG_CACHE_HOME` is defined, and
  ///   - `$HOME/.cache/<tool>` otherwise.
  ///
  /// The directory won't be created, the method merely returns the recommended
  /// location.
  ///
  /// On some platforms, this path may overlap with [runtimeHome] and
  /// [stateHome].
  ///
  /// Throws an [EnvironmentNotFoundException] if a necessary environment
  /// variable is undefined.
  late final String cacheHome =
      path.join(_baseDirectory(_XdgBaseDirectoryKind.cache)!, tool);

  /// Path of the directory where the tool will place its configuration.
  ///
  /// The configuration may be synchronized across devices by the OS and may
  /// survive application removal.
  ///
  /// This is a location appropriate for storing application specific
  /// configuration for the current user.
  ///
  /// The directory location depends on the current [Platform.operatingSystem]
  /// and what file types are stored:
  /// - on **Windows**:
  ///   - `%APPDATA%\<tool>`
  /// - on **Mac OS**:
  ///   - `$HOME/Library/Application Support/<tool>`
  /// - on **Linux**:
  ///   - `$XDG_CONFIG_HOME/<tool>` if `$XDG_CONFIG_HOME` is defined, and
  ///   - `$HOME/.config/<tool>` otherwise.
  ///
  /// The directory won't be created, the method merely returns the recommended
  /// location.
  ///
  /// On some platforms, this path may overlap with [dataHome].
  ///
  /// Throws an [EnvironmentNotFoundException] if a necessary environment
  /// variable is undefined.
  late final String configHome =
      path.join(_baseDirectory(_XdgBaseDirectoryKind.config)!, tool);

  /// Path of the directory where the tool will place its user data.
  ///
  /// The data may be backed up and synchronized to other devices by the
  /// operating system. For large data use [stateHome] instead.
  ///
  /// This is a location appropriate for storing application specific
  /// data for the current user. For example: documents created by the user.
  ///
  /// The directory location depends on the current [Platform.operatingSystem]:
  /// - on **Windows**:
  ///   - `%APPDATA%\<tool>`
  /// - on **Mac OS**:
  ///   - `$HOME/Library/Application Support/<tool>`
  /// - on **Linux**:
  ///   - `$XDG_DATA_HOME/<tool>` if `$XDG_DATA_HOME` is defined, and
  ///   - `$HOME/.local/share/<tool>` otherwise.
  ///
  /// The directory won't be created, the method merely returns the recommended
  /// location.
  ///
  /// On some platforms, this path may overlap with [configHome] and
  /// [stateHome].
  ///
  /// Throws an [EnvironmentNotFoundException] if a necessary environment
  /// variable is undefined.
  late final String dataHome =
      path.join(_baseDirectory(_XdgBaseDirectoryKind.data)!, tool);

  /// Path of the directory where the tool will place its runtime data.
  ///
  /// The runtime data may be deleted in between user logins by the OS. For data
  /// that needs to persist between sessions, use [stateHome] instead.
  ///
  /// This is a location appropriate for storing runtime data for the current
  /// session. For example: undo history.
  ///
  /// This directory might be undefined on Linux, in such case a warning should
  /// be printed and a suitable fallback (such as a temporary directory) should
  /// be used.
  ///
  /// The directory location depends on the current [Platform.operatingSystem]:
  /// - on **Windows**:
  ///   - `%LOCALAPPDATA%\<tool>`
  /// - on **Mac OS**:
  ///   - `$HOME/Library/Caches/TemporaryItems/<tool>`
  /// - on **Linux**:
  ///   - `$XDG_RUNTIME_HOME/<tool>` if `$XDG_RUNTIME_HOME` is defined, and
  ///   - `null` otherwise.
  ///
  /// The directory won't be created, the method merely returns the recommended
  /// location.
  ///
  /// On some platforms, this path may overlap [cacheHome] and [stateHome] or be
  /// nested in [cacheHome].
  ///
  /// Throws an [EnvironmentNotFoundException] if a necessary environment
  /// variable is undefined.
  late final String? runtimeHome =
      _join(_baseDirectory(_XdgBaseDirectoryKind.runtime), tool);

  /// Path of the directory where the tool will place its state.
  ///
  /// The state directory is likely not backed up or synchronized accross
  /// devices by the OS. For data that may be backed up and synchronized, use
  /// [dataHome] instead.
  ///
  /// This is a location appropriate for storing data which is either not
  /// important enougn, not small enough, or not portable enough to store in
  /// [dataHome]. For example: logs and indices.
  ///
  /// The directory location depends on the current [Platform.operatingSystem]:
  /// - on **Windows**:
  ///   - `%LOCALAPPDATA%\<tool>`
  /// - on **Mac OS**:
  ///   - `$HOME/Library/Application Support/<tool>`
  /// - on **Linux**:
  ///   - `$XDG_STATE_HOME/<tool>` if `$XDG_STATE_HOME` is defined, and
  ///   - `$HOME/.local/state/<tool>` otherwise.
  ///
  /// The directory won't be created, the method merely returns the recommended
  /// location.
  ///
  /// On some platforms, this path may overlap with [cacheHome], and
  /// [runtimeHome].
  ///
  /// Throws an [EnvironmentNotFoundException] if a necessary environment
  /// variable is undefined.
  late final String stateHome =
      path.join(_baseDirectory(_XdgBaseDirectoryKind.state)!, tool);

  String? _baseDirectory(_XdgBaseDirectoryKind directoryKind) {
    if (Platform.isWindows) {
      return _baseDirectoryWindows(directoryKind);
    }
    if (Platform.isMacOS) {
      return _baseDirectoryMacOs(directoryKind);
    }
    if (Platform.isLinux) {
      return _baseDirectoryLinux(directoryKind);
    }
    throw UnsupportedError('Unsupported platform: ${Platform.operatingSystem}');
  }

  String _baseDirectoryWindows(_XdgBaseDirectoryKind dir) => switch (dir) {
        _XdgBaseDirectoryKind.config ||
        _XdgBaseDirectoryKind.data =>
          _requireEnv('APPDATA'),
        _XdgBaseDirectoryKind.cache ||
        _XdgBaseDirectoryKind.runtime ||
        _XdgBaseDirectoryKind.state =>
          _requireEnv('LOCALAPPDATA'),
      };

  String _baseDirectoryMacOs(_XdgBaseDirectoryKind dir) => switch (dir) {
        _XdgBaseDirectoryKind.config ||
        // `$HOME/Library/Preferences/` may only contain `.plist` files, so use
        // `Application Support` instead.
        _XdgBaseDirectoryKind.data ||
        _XdgBaseDirectoryKind.state =>
          path.join(_home, 'Library', 'Application Support'),
        _XdgBaseDirectoryKind.cache => path.join(_home, 'Library', 'Caches'),
        _XdgBaseDirectoryKind.runtime =>
          // https://stackoverflow.com/a/76799489
          path.join(_home, 'Library', 'Caches', 'TemporaryItems'),
      };

  String? _baseDirectoryLinux(_XdgBaseDirectoryKind dir) {
    if (Platform.isLinux) {
      final xdgEnv = switch (dir) {
        _XdgBaseDirectoryKind.config => 'XDG_CONFIG_HOME',
        _XdgBaseDirectoryKind.data => 'XDG_DATA_HOME',
        _XdgBaseDirectoryKind.state => 'XDG_STATE_HOME',
        _XdgBaseDirectoryKind.cache => 'XDG_CACHE_HOME',
        _XdgBaseDirectoryKind.runtime => 'XDG_RUNTIME_DIR',
      };
      final envVar = _environment[xdgEnv];
      if (envVar != null) {
        return envVar;
      }
    }

    switch (dir) {
      case _XdgBaseDirectoryKind.runtime:
        // Applications should chose a different directory and print a warning.
        return null;
      case _XdgBaseDirectoryKind.cache:
        return path.join(_home, '.cache');
      case _XdgBaseDirectoryKind.config:
        return path.join(_home, '.config');
      case _XdgBaseDirectoryKind.data:
        return path.join(_home, '.local', 'share');
      case _XdgBaseDirectoryKind.state:
        return path.join(_home, '.local', 'state');
    }
  }

  String get _home => _requireEnv('HOME');

  String _requireEnv(String name) =>
      _environment[name] ?? (throw EnvironmentNotFoundException(name));
}

/// A kind from the XDG base directory specification for Linux.
///
/// MacOS and Windows have less kinds.
enum _XdgBaseDirectoryKind {
  cache,
  config,
  data,
  // Executables are also mentioned in the XDG spec, but these do not have as
  // well defined of locations on Windows and MacOS.
  runtime,
  state,
}

String? _join(String? part1, String? part2) {
  if (part1 == null || part2 == null) {
    return null;
  }
  return path.join(part1, part2);
}
