// 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:convert';
import 'dart:io' as io;
import 'dart:typed_data';

import 'package:code_assets/code_assets.dart' show OS;
import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:hooks_runner/hooks_runner.dart' show Target;
import 'package:http/http.dart' as http;

/// S_IXUSR bit from POSIX sys/stat.h.
///
/// When the file is user executable, this bit should be set in its mode.
const sIxusr = 0x40;

/// Represents a folder in Dart archive.
///
/// See https://dart.dev/get-dart/archive.
class ArchiveFolder {
  final String version;
  final String revision;
  final Channel channel;

  Uri fileUri(String path, {required Stage stage}) => SdkCache.archiveUri(
    channel: channel,
    version: 'hash/$revision',
    stage: stage,
    path: path,
  );

  ArchiveFolder({
    required this.version,
    required this.revision,
    required this.channel,
  });
}

/// Cache for retrieving artifacts that are not shipped with the Dart SDK.
///
/// Some binaries required by DartDev are not included with the distributed
/// Dart SDK but can be downloaded from the Dart archive. This class downloads
/// requested artifacts and stores them on disk (usually in ~/.dart).
class SdkCache {
  final FileSystem fs;
  late final Directory directory;
  final bool verbose;
  final http.Client _httpClient;
  final StringSink _stderr;
  final io.ProcessResult Function(String) _setUserExecutable;

  SdkCache({
    required String directory,
    required this.verbose,
    http.Client Function()? createHttpClient,
    FileSystem? fs,
    StringSink? stderr,
    io.ProcessResult Function(String)? chmod,
    http.Client? httpClient,
  }) : _setUserExecutable = chmod ?? _defaultSetUserExecutable,
       _httpClient = httpClient ?? http.Client(),
       _stderr = stderr ?? io.stderr,
       fs = fs ?? LocalFileSystem() {
    this.directory = this.fs.directory(directory);
  }

  /// Determines the remote location of artifacts for the current SDK.
  ///
  /// The stage depends on host operating system: macOS requires signed
  /// executables.
  ///
  /// Additionally, for the main channel it validates that the given revision
  /// exists in the remote archive, or falls back to the latest revision if it
  /// does not (this may happen when Dart SDK is built locally from a local
  /// revision, or built with RBE, in which case there's no revision at all).
  Future<ArchiveFolder> resolveVersion({
    required String version,
    required String revision,
    required String channelName,
    Target? host,
  }) async {
    host ??= Target.current;
    final channel = Channel.fromString(channelName);
    if (channel == null) {
      throw ArgumentError('Unsupported channel: "$channelName".');
    }

    final folderFromArgs = ArchiveFolder(
      version: version,
      revision: revision,
      channel: channel,
    );
    if (channel != Channel.main) {
      // Past main channel, we always assume that given version and revision
      // must exist on the server.
      if (revision.isEmpty) {
        throw ArgumentError(
          'Channel "${channel.name}" requires valid revision.',
        );
      }

      return folderFromArgs;
    }

    // Require signed artifacts on macOS past main channel (main channel
    // releases aren't signed).
    final stage = host.os == OS.macOS && channel != Channel.main
        ? Stage.signed
        : Stage.raw;

    // On the main channel, on contrary, we do not trust the revision, because
    // it can be empty (if Dart SDK is built with RBE), or be at the local
    // commit revision, which does not exist on storage.
    if (revision.isNotEmpty) {
      // Check that the given revision exists.
      var exists = await _exists(
        folderFromArgs.fileUri('VERSION', stage: stage),
      );

      if (exists) {
        return ArchiveFolder(
          version: version,
          revision: revision,
          channel: channel,
        );
      } else {
        if (verbose) {
          _stderr.writeln('Cannot find revision $revision in an archive.');
        }
      }
    }

    // No revision or invalid revision, checking the latest version.
    _stderr.writeln('Checking the latest available revision...');
    (version, revision) = await _getLatestVersion(
      channel: channel,
      stage: stage,
    );
    if (verbose) {
      _stderr.writeln('Using revision $revision.');
    }
    return ArchiveFolder(
      version: version,
      revision: revision,
      channel: channel,
    );
  }

  void _ensureExecutable(File destinationFile, OS hostOS) {
    if (hostOS == OS.windows) {
      return;
    }

    final isUserExecutable = destinationFile.statSync().mode & sIxusr == sIxusr;
    if (isUserExecutable) {
      return;
    }

    final chmodResult = _setUserExecutable(destinationFile.path);
    if (chmodResult.exitCode != 0) {
      throw SdkCacheException(
        'Cannot make ${destinationFile.path} executable, chmod failed.\n'
        'exitCode: ${chmodResult.exitCode}\n'
        'stderr: ${chmodResult.stderr}',
      );
    }
  }

  Future<String> ensureGenSnapshot({
    required ArchiveFolder archiveFolder,
    required Target target,
    Target? host,
  }) {
    host ??= Target.current;
    // Determine a file base name.
    var basename = 'gen_snapshot_${host}_$target';
    if (host.os == OS.windows) {
      basename = '$basename.exe';
    }
    return ensureArtifact(
      archiveFolder: archiveFolder,
      host: host,
      target: target,
      basename: basename,
      isExecutable: true,
    );
  }

  Future<String> ensureDartAotRuntime({
    required ArchiveFolder archiveFolder,
    required Target target,
    Target? host,
  }) {
    host ??= Target.current;
    return ensureArtifact(
      archiveFolder: archiveFolder,
      basename: 'dartaotruntime_$target',
      target: target,
      host: host,
      isExecutable: false,
    );
  }

  Future<String> ensureArtifact({
    required ArchiveFolder archiveFolder,
    required String basename,
    required Target target,
    required Target host,
    required bool isExecutable,
  }) async {
    // Calculate the local path.
    var localFile = directory
        .childDirectory(archiveFolder.version)
        .childFile(basename);
    if (localFile.existsSync()) {
      if (isExecutable) {
        _ensureExecutable(localFile, host.os);
      }
      return localFile.path;
    }

    localFile.parent.createSync(recursive: true);
    final uri = archiveFolder.fileUri(
      'sdk/$basename',
      stage: resolveStage(
        channel: archiveFolder.channel,
        isExecutable: isExecutable,
        hostOS: host.os,
      ),
    );

    try {
      localFile.writeAsBytesSync(await _download(uri));
    } catch (_) {
      _stderr.writeln('Failed to download $uri to ${localFile.path}.');
      _stderr.writeln('If the problem persists, try downloading it manually.');
      rethrow;
    }

    if (isExecutable) {
      _ensureExecutable(localFile, host.os);
    }
    return localFile.path;
  }

  /// For a given channel, find the latest available revision.
  Future<(String, String)> _getLatestVersion({
    required Channel channel,
    required Stage stage,
  }) async {
    final json = jsonDecode(
      utf8.decode(
        await _download(
          archiveUri(
            channel: channel,
            stage: stage,
            version: 'latest',
            path: 'VERSION',
          ),
        ),
      ),
    );
    return (json['version'] as String, json['revision'] as String);
  }

  Future<bool> _exists(Uri uri) async {
    if (verbose) {
      _stderr.writeln('Checking $uri...');
    }
    final response = await _httpClient.head(uri);
    if (response.statusCode == io.HttpStatus.ok) {
      return true;
    } else if (response.statusCode == io.HttpStatus.notFound) {
      return false;
    } else {
      throw SdkCacheException('HEAD $uri failed: ${response.statusCode}');
    }
  }

  Future<Uint8List> _download(Uri uri) async {
    if (verbose) {
      _stderr.writeln('Downloading $uri...');
    }
    final response = await _httpClient.get(uri);
    if (response.statusCode != io.HttpStatus.ok) {
      throw SdkCacheException('GET $uri failed: ${response.statusCode}');
    }
    return response.bodyBytes;
  }

  static Stage resolveStage({
    required Channel channel,
    required bool isExecutable,
    required OS hostOS,
  }) {
    if (channel == Channel.main || !isExecutable) {
      return Stage.raw;
    }

    return hostOS == OS.macOS ? Stage.signed : Stage.raw;
  }

  static Uri archiveUri({
    required Channel channel,
    required Stage stage,
    required String version,
    required String path,
  }) => Uri.https(
    'storage.googleapis.com',
    'dart-archive/channels/${channel.name}/${stage.name}/$version/$path',
  );

  /// Default implementation fdor making a [path] executable.
  ///
  /// For testability, the actual implementation can be overridden in [SdkCache]
  /// constructor.
  static io.ProcessResult _defaultSetUserExecutable(String path) =>
      io.Process.runSync('chmod', ['u+x', path]);
}

/// Release stage.
///
/// The stage is related to an internal release process, and not all artifacts
/// are available at all stages.
///
/// E.g. signed stage contains only signed SDK and executables for macOS.
enum Stage {
  raw('raw'),
  signed('signed');

  final String name;

  const Stage(this.name);
}

/// Release channel (e.g. beta, stable).
///
/// It corresponds to release channels at https://dart.dev/get-dart/archive and
/// does not necessarily maps to Git branches.
enum Channel {
  main('main'),
  dev('dev'),
  beta('beta'),
  stable('stable');

  final String name;

  const Channel(this.name);

  static Channel? fromString(String name) {
    for (final value in Channel.values) {
      if (value.name == name) {
        return value;
      }
    }
    return null;
  }
}

class SdkCacheException implements Exception {
  final String message;

  SdkCacheException(this.message);

  @override
  String toString() => 'SdkCacheException: $message';
}
