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

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/project.dart';
import 'package:analyzer/src/lint/pub.dart';
import 'package:linter/src/analyzer.dart';

class CollectingSink extends MockIOSink {
  final StringBuffer buffer = StringBuffer();

  @override
  String toString() => buffer.toString();

  String trim() => toString().trim();

  @override
  write(obj) {
    buffer.write(obj);
  }

  @override
  writeln([Object obj = '']) {
    buffer.writeln(obj);
  }
}

class MockErrorType implements ErrorType {
  @override
  String displayName;

  @override
  String name;

  @override
  int ordinal;

  @override
  ErrorSeverity severity;

  @override
  int compareTo(ErrorType other) => 0;

  @override
  String toString() => 'MockErrorType';
}

class MockIOSink implements IOSink {
  @override
  Encoding encoding;

  @override
  Future get done => null;

  @override
  void add(List<int> data) {}

  @override
  void addError(Object error, [StackTrace stackTrace]) {}

  @override
  Future addStream(Stream<List<int>> stream) => null;

  @override
  Future close() => null;

  @override
  Future flush() => null;

  @override
  void write(Object obj) {}

  @override
  void writeAll(Iterable objects, [String separator = '']) {}

  @override
  void writeCharCode(int charCode) {}

  @override
  void writeln([Object obj = '']) {}
}

class MockPubVisitor implements PubspecVisitor {
  @override
  visitPackageAuthor(PSEntry author) {
    throw Exception();
  }

  @override
  visitPackageAuthors(PSNodeList authors) {
    throw Exception();
  }

  @override
  visitPackageDependencies(PSDependencyList dependencies) {
    throw Exception();
  }

  @override
  visitPackageDependency(PSDependency dependency) {
    throw Exception();
  }

  @override
  visitPackageDependencyOverride(PSDependency dependency) {
    throw Exception();
  }

  @override
  visitPackageDependencyOverrides(PSDependencyList dependencies) {
    throw Exception();
  }

  @override
  visitPackageDescription(PSEntry description) {
    throw Exception();
  }

  @override
  visitPackageDevDependencies(PSDependencyList dependencies) {
    throw Exception();
  }

  @override
  visitPackageDevDependency(PSDependency dependency) {
    throw Exception();
  }

  @override
  visitPackageDocumentation(PSEntry documentation) {
    throw Exception();
  }

  @override
  visitPackageHomepage(PSEntry homepage) {
    throw Exception();
  }

  @override
  visitPackageName(PSEntry name) {
    throw Exception();
  }

  @override
  visitPackageVersion(PSEntry version) {
    throw Exception();
  }
}

class MockReporter implements Reporter {
  List<LinterException> exceptions = <LinterException>[];

  List<String> warnings = <String>[];

  MockReporter();

  @override
  void exception(LinterException exception) {
    exceptions.add(exception);
  }

  @override
  void warn(String message) {
    warnings.add(message);
  }
}

class MockRule implements LintRule {
  @override
  ErrorReporter reporter;

  @override
  String description;

  @override
  String details;

  ProjectVisitor projectVisitor;

  PubspecVisitor pubspecVisitor;
  AstVisitor visitor;

  @override
  Group group;

  @override
  LintCode lintCode;

  @override
  Maturity maturity;

  @override
  String name;

  @override
  int compareTo(LintRule other) => 0;

  @override
  ProjectVisitor getProjectVisitor() => projectVisitor;

  @override
  PubspecVisitor getPubspecVisitor() => pubspecVisitor;

  @override
  AstVisitor getVisitor() => visitor;

  @override
  noSuchMethod(Invocation invocation) => null;

  @override
  void reportPubLint(PSNode node) {}
}

class MockSource implements Source {
  @override
  TimestampedData<String> contents;

  @override
  String encoding;

  @override
  String fullName;

  @override
  bool isInSystemLibrary;

  @override
  Source librarySource;

  @override
  int modificationStamp;

  @override
  String shortName;

  @override
  Source source;

  @override
  Uri uri;

  @override
  UriKind uriKind;

  @override
  // ignore: avoid_returning_null
  bool exists() => null;
}

class TestErrorCode extends ErrorCode {
  @override
  ErrorSeverity errorSeverity;

  @override
  ErrorType type;

  TestErrorCode(String name, String message) : super(name, message);
}
