// 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 respect 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_DIR/<tool>` if `$XDG_RUNTIME_DIR` 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 across
  /// 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 enough, 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 choose 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);
}
