// Copyright (c) 2020, 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';

extension TestGeneratorStringExtension on String {
  String upperCaseFirst() => "${this[0].toUpperCase()}${this.substring(1)}";

  String lowerCaseFirst() => "${this[0].toLowerCase()}${this.substring(1)}";

  String makeCComment() => "// " + split("\n").join("\n// ");

  String makeDartDocComment() => "/// " + split("\n").join("\n/// ");

  String limitTo(int length) {
    if (this.length > length) {
      return substring(0, length);
    }
    return this;
  }

  String trimCouts() => replaceAll('" << "', '').replaceAll('"<< "', '');
}

Future<void> runProcess(String executable, List<String> arguments) async {
  final commandString = [executable, ...arguments].join(' ');
  stdout.writeln('Running `$commandString`.');
  final process = await Process.start(
    executable,
    arguments,
    runInShell: true,
    includeParentEnvironment: true,
  ).then((process) {
    process.stdout.forEach(stdout.add);
    process.stderr.forEach(stderr.add);
    return process;
  });
  final exitCode = await process.exitCode;
  if (exitCode != 0) {
    final message = 'Command `$commandString` failed with exit code $exitCode.';
    stderr.writeln(message);
    throw Exception(message);
  }
  stdout.writeln('Command `$commandString` done.');
}

String headerCommon({
  required int copyrightYear,
  required String generatorPath,
}) {
  final year = copyrightYear;
  return """
// Copyright (c) $year, 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.
//
// This file has been automatically generated. Please do not edit it manually.
// Generated by $generatorPath.""";
}

String headerC({required int copyrightYear, required String generatorPath}) {
  return """
${headerCommon(copyrightYear: copyrightYear, generatorPath: generatorPath)}

#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>

#include <cmath>
#include <iostream>
#include <limits>

#if defined(_WIN32)
#define DART_EXPORT extern "C" __declspec(dllexport)
#else
#define DART_EXPORT                                                            \\
  extern "C" __attribute__((visibility("default"))) __attribute((used))
#endif

namespace dart {

#define CHECK(X)                                                               \\
  if (!(X)) {                                                                  \\
    fprintf(stderr, "%s\\n", "Check failed: " #X);                              \\
    return 1;                                                                  \\
  }

#define CHECK_EQ(X, Y) CHECK((X) == (Y))

// Works for positive, negative and zero.
#define CHECK_APPROX(EXPECTED, ACTUAL)                                         \\
  CHECK(((EXPECTED * 0.99) <= (ACTUAL) && (EXPECTED * 1.01) >= (ACTUAL)) ||    \\
        ((EXPECTED * 0.99) >= (ACTUAL) && (EXPECTED * 1.01) <= (ACTUAL)))

""";
}

const footerC = """

}  // namespace dart
""";
