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

import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analyzer/dart/ast/ast.dart' as engine;
import 'package:analyzer/dart/element/element.dart' as engine;
import 'package:analyzer/dart/element/type.dart' as engine;
import 'package:analyzer/error/error.dart' as engine;
import 'package:analyzer/src/error/codes.dart' as engine;
import 'package:analyzer/src/generated/source.dart' as engine;
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'constants.dart';
import 'mocks.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(AnalysisErrorTest);
    defineReflectiveTests(EnumTest);
  });
}

@reflectiveTest
class AnalysisErrorTest {
  MockSource source = new MockSource();
  engine.LineInfo lineInfo;
  MockAnalysisError engineError;

  void setUp() {
    // prepare Source
    source.fullName = 'foo.dart';
    // prepare LineInfo
    lineInfo = new engine.LineInfo([0, 5, 9, 20]);
    // prepare AnalysisError
    engineError = new MockAnalysisError(source,
        engine.CompileTimeErrorCode.AMBIGUOUS_EXPORT, 10, 20, 'my message');
  }

  void tearDown() {
    source = null;
    engineError = null;
  }

  void test_fromEngine_hasCorrection() {
    engineError.correction = 'my correction';
    AnalysisError error = newAnalysisError_fromEngine(lineInfo, engineError);
    expect(error.toJson(), {
      SEVERITY: 'ERROR',
      TYPE: 'COMPILE_TIME_ERROR',
      LOCATION: {
        FILE: 'foo.dart',
        OFFSET: 10,
        LENGTH: 20,
        START_LINE: 3,
        START_COLUMN: 2
      },
      MESSAGE: 'my message',
      CORRECTION: 'my correction',
      CODE: 'ambiguous_export',
      HAS_FIX: false
    });
  }

  void test_fromEngine_noCorrection() {
    engineError.correction = null;
    AnalysisError error = newAnalysisError_fromEngine(lineInfo, engineError);
    expect(error.toJson(), {
      SEVERITY: 'ERROR',
      TYPE: 'COMPILE_TIME_ERROR',
      LOCATION: {
        FILE: 'foo.dart',
        OFFSET: 10,
        LENGTH: 20,
        START_LINE: 3,
        START_COLUMN: 2
      },
      MESSAGE: 'my message',
      CODE: 'ambiguous_export',
      HAS_FIX: false
    });
  }

  void test_fromEngine_noLineInfo() {
    engineError.correction = null;
    AnalysisError error = newAnalysisError_fromEngine(null, engineError);
    expect(error.toJson(), {
      SEVERITY: 'ERROR',
      TYPE: 'COMPILE_TIME_ERROR',
      LOCATION: {
        FILE: 'foo.dart',
        OFFSET: 10,
        LENGTH: 20,
        START_LINE: -1,
        START_COLUMN: -1
      },
      MESSAGE: 'my message',
      CODE: 'ambiguous_export',
      HAS_FIX: false
    });
  }
}

@reflectiveTest
class EnumTest {
  void test_AnalysisErrorSeverity() {
    new EnumTester<engine.ErrorSeverity, AnalysisErrorSeverity>().run(
        (engine.ErrorSeverity engineErrorSeverity) =>
            new AnalysisErrorSeverity(engineErrorSeverity.name),
        exceptions: {engine.ErrorSeverity.NONE: null});
  }

  void test_AnalysisErrorType() {
    new EnumTester<engine.ErrorType, AnalysisErrorType>().run(
        (engine.ErrorType engineErrorType) =>
            new AnalysisErrorType(engineErrorType.name));
  }

  void test_ElementKind() {
    new EnumTester<engine.ElementKind, ElementKind>()
        .run(convertElementKind, exceptions: {
      // TODO(paulberry): do any of the exceptions below constitute bugs?
      engine.ElementKind.DYNAMIC: ElementKind.UNKNOWN,
      engine.ElementKind.ERROR: ElementKind.UNKNOWN,
      engine.ElementKind.EXPORT: ElementKind.UNKNOWN,
      engine.ElementKind.GENERIC_FUNCTION_TYPE: ElementKind.FUNCTION_TYPE_ALIAS,
      engine.ElementKind.IMPORT: ElementKind.UNKNOWN,
      engine.ElementKind.NAME: ElementKind.UNKNOWN,
      engine.ElementKind.UNIVERSE: ElementKind.UNKNOWN
    });
  }

  void test_SearchResultKind() {
    // TODO(paulberry): why does the MatchKind class exist at all?  Can't we
    // use SearchResultKind inside the analysis server?
    new EnumTester<MatchKind, SearchResultKind>()
        .run(newSearchResultKind_fromEngine);
  }
}

/**
 * Helper class for testing the correspondence between an analysis engine enum
 * and an analysis server API enum.
 */
class EnumTester<EngineEnum, ApiEnum> {
  /**
   * Test that the function [convert] properly converts all possible values of
   * [EngineEnum] to an [ApiEnum] with the same name, with the exceptions noted
   * in [exceptions].  For each key in [exceptions], if the corresponding value
   * is null, then we check that converting the given key results in an error.
   * If the corresponding value is an [ApiEnum], then we check that converting
   * the given key results in the given value.
   */
  void run(ApiEnum convert(EngineEnum value),
      {Map<EngineEnum, ApiEnum> exceptions: const {}}) {
    ClassMirror engineClass = reflectClass(EngineEnum);
    engineClass.staticMembers.forEach((Symbol symbol, MethodMirror method) {
      if (symbol == #values) {
        return;
      }
      if (!method.isGetter) {
        return;
      }
      String enumName = MirrorSystem.getName(symbol);
      EngineEnum engineValue =
          engineClass.getField(symbol).reflectee as EngineEnum;
      expect(engineValue, new TypeMatcher<EngineEnum>());
      if (exceptions.containsKey(engineValue)) {
        ApiEnum expectedResult = exceptions[engineValue];
        if (expectedResult == null) {
          expect(() {
            convert(engineValue);
          }, throwsException);
        } else {
          ApiEnum apiValue = convert(engineValue);
          expect(apiValue, equals(expectedResult));
        }
      } else {
        ApiEnum apiValue = convert(engineValue);
        expect((apiValue as dynamic).name, equals(enumName));
      }
    });
  }
}

class MockAnalysisError implements engine.AnalysisError {
  @override
  MockSource source;

  @override
  engine.ErrorCode errorCode;

  @override
  int offset;

  @override
  String message;

  @override
  String correction = null;

  @override
  bool isStaticOnly;

  @override
  int length;

  MockAnalysisError(
      this.source, this.errorCode, this.offset, this.length, this.message);
}
