// Copyright (c) 2019, 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 'package:analysis_tool/package_root.dart' as package_root;
import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/overlay_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:test/test.dart';

main() async {
  SnippetTester tester = SnippetTester();
  await tester.verify();
  if (tester.output.isNotEmpty) {
    fail(tester.output.toString());
  }
}

class SnippetTester {
  final OverlayResourceProvider provider;
  final Folder docFolder;
  final String snippetDirPath;
  final String snippetPath;

  final StringBuffer output = StringBuffer();

  factory SnippetTester() {
    var provider = OverlayResourceProvider(PhysicalResourceProvider.INSTANCE);
    var packageRoot = provider.pathContext.normalize(package_root.packageRoot);
    var analyzerPath = provider.pathContext.join(packageRoot, 'analyzer');
    var docPath = provider.pathContext.join(analyzerPath, 'doc');
    var docFolder = provider.getFolder(docPath);
    var snippetDirPath =
        provider.pathContext.join(analyzerPath, 'test', 'snippets');
    var snippetPath = provider.pathContext.join(snippetDirPath, 'snippet.dart');
    return SnippetTester._(provider, docFolder, snippetDirPath, snippetPath);
  }

  SnippetTester._(
      this.provider, this.docFolder, this.snippetDirPath, this.snippetPath);

  Future<void> verify() async {
    await verifyFolder(docFolder);
  }

  Future<void> verifyFile(File file) async {
    String content = file.readAsStringSync();
    List<String> lines = const LineSplitter().convert(content);
    List<String> codeLines = [];
    bool inCode = false;
    for (int i = 0; i < lines.length; i++) {
      String line = lines[i];
      if (line == '```dart') {
        if (inCode) {
          // TODO(brianwilkerson) Report this.
        }
        inCode = true;
      } else if (line == '```') {
        if (!inCode) {
          // TODO(brianwilkerson) Report this.
        }
        await verifySnippet(file, codeLines.join('\n'));
        codeLines.clear();
        inCode = false;
      } else if (inCode) {
        codeLines.add(line);
      }
    }
  }

  Future<void> verifyFolder(Folder folder) async {
    for (Resource child in folder.getChildren()) {
      if (child is File) {
        if (child.shortName.endsWith('.md')) {
          await verifyFile(child);
        }
      } else if (child is Folder) {
        await verifyFolder(child);
      }
    }
  }

  Future<void> verifySnippet(File file, String snippet) async {
    // TODO(brianwilkerson) When the files outside of 'src' contain only public
    //  API, write code to compute the list of imports so that new public API
    //  will automatically be allowed.
    String imports = '''
import 'dart:math' as math;

import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/visitor.dart';

''';
    provider.setOverlay(snippetPath,
        content: '''
$imports
$snippet
''',
        modificationStamp: 1);
    try {
      AnalysisContextCollection collection = AnalysisContextCollection(
          includedPaths: <String>[snippetDirPath], resourceProvider: provider);
      List<AnalysisContext> contexts = collection.contexts;
      if (contexts.length != 1) {
        fail('The snippets directory contains multiple analysis contexts.');
      }
      ErrorsResult results =
          await contexts[0].currentSession.getErrors(snippetPath);
      Iterable<AnalysisError> errors = results.errors.where((error) {
        ErrorCode errorCode = error.errorCode;
        return errorCode != HintCode.UNUSED_IMPORT &&
            errorCode != HintCode.UNUSED_LOCAL_VARIABLE;
      });
      if (errors.isNotEmpty) {
        String filePath =
            provider.pathContext.relative(file.path, from: docFolder.path);
        if (output.isNotEmpty) {
          output.writeln();
        }
        output.writeln('Errors in snippet in "$filePath":');
        output.writeln();
        output.writeln(snippet);
        output.writeln();
        int importsLength = imports.length + 1; // account for the '\n'.
        for (var error in errors) {
          writeError(error, importsLength);
        }
      }
    } catch (exception, stackTrace) {
      if (output.isNotEmpty) {
        output.writeln();
      }
      output.writeln('Exception while analyzing "$snippet"');
      output.writeln();
      output.writeln(exception);
      output.writeln(stackTrace);
    } finally {
      provider.removeOverlay(snippetPath);
    }
  }

  void writeError(AnalysisError error, int prefixLength) {
    output.write(error.errorCode);
    output.write(' (');
    output.write(error.offset - prefixLength);
    output.write(', ');
    output.write(error.length);
    output.write(') ');
    output.writeln(error.message);
  }
}
