// 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 '../base/error_handling_io.dart';
import '../base/file_system.dart';
import '../base/logger.dart';

/// A service for creating and parsing [Depfile]s.
class DepfileService {
  DepfileService({
    required Logger logger,
    required FileSystem fileSystem,
  }) : _logger = logger,
       _fileSystem = fileSystem;

  final Logger _logger;
  final FileSystem _fileSystem;
  static final RegExp _separatorExpr = RegExp(r'([^\\]) ');
  static final RegExp _escapeExpr = RegExp(r'\\(.)');

  /// Given an [depfile] File, write the depfile contents.
  ///
  /// If both [inputs] and [outputs] are empty, ensures the file does not
  /// exist. This can be overridden with the [writeEmpty] parameter when
  /// both static and runtime dependencies exist and it is not desired
  /// to force a rerun due to no depfile.
  void writeToFile(Depfile depfile, File output, {bool writeEmpty = false}) {
    if (depfile.inputs.isEmpty && depfile.outputs.isEmpty && !writeEmpty) {
      ErrorHandlingFileSystem.deleteIfExists(output);
      return;
    }
    final StringBuffer buffer = StringBuffer();
    _writeFilesToBuffer(depfile.outputs, buffer);
    buffer.write(': ');
    _writeFilesToBuffer(depfile.inputs, buffer);
    output.writeAsStringSync(buffer.toString());
  }

  /// Parse the depfile contents from [file].
  ///
  /// If the syntax is invalid, returns an empty [Depfile].
  Depfile parse(File file) {
    final String contents = file.readAsStringSync();
    final List<String> colonSeparated = contents.split(': ');
    if (colonSeparated.length != 2) {
      _logger.printError('Invalid depfile: ${file.path}');
      return const Depfile(<File>[], <File>[]);
    }
    final List<File> inputs = _processList(colonSeparated[1].trim());
    final List<File> outputs = _processList(colonSeparated[0].trim());
    return Depfile(inputs, outputs);
  }


  /// Parse the output of dart2js's used dependencies.
  ///
  /// The [file] contains a list of newline separated file URIs. The output
  /// file must be manually specified.
  Depfile parseDart2js(File file, File output) {
    final List<File> inputs = <File>[];
    for (final String rawUri in file.readAsLinesSync()) {
      if (rawUri.trim().isEmpty) {
        continue;
      }
      final Uri? fileUri = Uri.tryParse(rawUri);
      if (fileUri == null) {
        continue;
      }
      if (fileUri.scheme != 'file') {
        continue;
      }
      inputs.add(_fileSystem.file(fileUri));
    }
    return Depfile(inputs, <File>[output]);
  }

  void _writeFilesToBuffer(List<File> files, StringBuffer buffer) {
    for (final File outputFile in files) {
      if (_fileSystem.path.style.separator == r'\') {
        // backslashes and spaces in a depfile have to be escaped if the
        // platform separator is a backslash.
        final String path = outputFile.path
          .replaceAll(r'\', r'\\')
          .replaceAll(r' ', r'\ ');
        buffer.write(' $path');
      } else {
        final String path = outputFile.path
          .replaceAll(r' ', r'\ ');
        buffer.write(' $path');
      }
    }
  }

  List<File> _processList(String rawText) {
    return rawText
    // Put every file on right-hand side on the separate line
        .replaceAllMapped(_separatorExpr, (Match match) => '${match.group(1)}\n')
        .split('\n')
    // Expand escape sequences, so that '\ ', for example,ß becomes ' '
        .map<String>((String path) => path.replaceAllMapped(_escapeExpr, (Match match) => match.group(1)!).trim())
        .where((String path) => path.isNotEmpty)
    // The tool doesn't write duplicates to these lists. This call is an attempt to
    // be resilient to the outputs of other tools which write or user edits to depfiles.
        .toSet()
        .map(_fileSystem.file)
        .toList();
  }
}

/// A class for representing depfile formats.
class Depfile {
  /// Create a [Depfile] from a list of [input] files and [output] files.
  const Depfile(this.inputs, this.outputs);

  /// The input files for this depfile.
  final List<File> inputs;

  /// The output files for this depfile.
  final List<File> outputs;
}
