// 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 'package:args/args.dart';
import 'package:conductor_core/src/stdio.dart';
import 'package:test/test.dart';

export 'package:test/test.dart' hide isInstanceOf;
export '../../../../packages/flutter_tools/test/src/fake_process_manager.dart';

Matcher throwsAssertionWith(String messageSubString) {
  return throwsA(
      isA<AssertionError>().having(
          (AssertionError e) => e.toString(),
          'description',
          contains(messageSubString),
      ),
  );
}

Matcher throwsExceptionWith(String messageSubString) {
  return throwsA(
      isA<Exception>().having(
          (Exception e) => e.toString(),
          'description',
          contains(messageSubString),
      ),
  );
}

class TestStdio extends Stdio {
  TestStdio({
    this.verbose = false,
    List<String>? stdin,
  }) : stdin = stdin ?? <String>[];

  String get error => logs.where((String log) => log.startsWith(r'[error] ')).join('\n');

  String get stdout => logs.where((String log) {
    return log.startsWith(r'[status] ') || log.startsWith(r'[trace] ') || log.startsWith(r'[write] ');
  }).join('\n');

  final bool verbose;
  final List<String> stdin;

  @override
  String readLineSync() {
    if (stdin.isEmpty) {
      throw Exception('Unexpected call to readLineSync!');
    }
    return stdin.removeAt(0);
  }
}

class FakeArgResults implements ArgResults {
  FakeArgResults({
    required String? level,
    required String candidateBranch,
    String remote = 'upstream',
    bool justPrint = false,
    bool autoApprove = true, // so we don't have to mock stdin
    bool help = false,
    bool force = false,
    bool skipTagging = false,
  }) : _parsedArgs = <String, dynamic>{
    'increment': level,
    'candidate-branch': candidateBranch,
    'remote': remote,
    'just-print': justPrint,
    'yes': autoApprove,
    'help': help,
    'force': force,
    'skip-tagging': skipTagging,
  };

  @override
  String? name;

  @override
  ArgResults? command;

  @override
  final List<String> rest = <String>[];

  @override
  List<String> get arguments {
    assert(false, 'not yet implemented');
    return <String>[];
  }

  final Map<String, dynamic> _parsedArgs;

  @override
  Iterable<String> get options {
    assert(false, 'not yet implemented');
    return <String>[];
  }

  @override
  dynamic operator [](String name) {
    return _parsedArgs[name];
  }

  @override
  bool wasParsed(String name) {
    assert(false, 'not yet implemented');
    return false;
  }
}
