// 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.

library test.domain.context;

import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_context.dart';
import 'package:analysis_server/src/protocol.dart';
import 'package:analysis_server/src/resource.dart';
import 'package:unittest/unittest.dart';

import 'mocks.dart';

main() {
  group('ContextDomainHandlerTest', () {
    // TODO(scheglov) remove or move to the 'analysis' domain
//    test('applyChanges', ContextDomainHandlerTest.applyChanges);
    test('createChangeSet', ContextDomainHandlerTest.createChangeSet);
    test('createChangeSet_onlyAdded', ContextDomainHandlerTest.createChangeSet_onlyAdded);
    // TODO(scheglov) remove or move to the 'analysis' domain
//    test('setOptions', ContextDomainHandlerTest.setOptions);
//    test('setPrioritySources_empty', ContextDomainHandlerTest.setPrioritySources_empty);
//    test('setPrioritySources_nonEmpty', ContextDomainHandlerTest.setPrioritySources_nonEmpty);
  });
}

class ContextDomainHandlerTest {
  static int contextIdCounter = 0;

  // TODO(scheglov) remove or move to the 'analysis' domain
//  static void applyChanges() {
//    AnalysisServer server = new AnalysisServer(new MockServerChannel());
//    String contextId = _createContext(server);
//    ChangeSet changeSet = new ChangeSet();
//    ContextDomainHandler handler = new ContextDomainHandler(server);
//
//    Request request = new Request('0', ContextDomainHandler.APPLY_CHANGES_NAME);
//    request.setParameter(ContextDomainHandler.CONTEXT_ID_PARAM, contextId);
//    request.setParameter(ContextDomainHandler.SOURCES_PARAM, []);
//    request.setParameter(ContextDomainHandler.CHANGES_PARAM, {
//      ContextDomainHandler.ADDED_PARAM : ['ffile:/one.dart'],
//      ContextDomainHandler.MODIFIED_PARAM : ['ffile:/two.dart'],
//      ContextDomainHandler.REMOVED_PARAM : ['ffile:/three.dart']
//    });
//    expect(server.contextWorkQueue, isEmpty);
//    Response response = handler.handleRequest(request);
//    expect(server.contextWorkQueue, hasLength(1));
//    expect(response.toJson(), equals({
//      Response.ID: '0'
//    }));
//  }

  static void createChangeSet() {
    AnalysisServer server = new AnalysisServer(
        new MockServerChannel(),
        PhysicalResourceProvider.INSTANCE);
    Request request = new Request('0', ContextDomainHandler.APPLY_CHANGES_NAME);
    ContextDomainHandler handler = new ContextDomainHandler(server);
    SourceFactory sourceFactory = new SourceFactory([new FileUriResolver()]);
    ChangeSet changeSet = handler.createChangeSet(request, sourceFactory,
        new RequestDatum(request, ContextDomainHandler.CHANGES_PARAM, {
      ContextDomainHandler.ADDED_PARAM: ['ffile:/one.dart'],
      ContextDomainHandler.MODIFIED_PARAM: [],
      ContextDomainHandler.REMOVED_PARAM: ['ffile:/two.dart',
          'ffile:/three.dart']
    }));
    expect(changeSet.addedSources, hasLength(equals(1)));
    expect(changeSet.changedSources, hasLength(equals(0)));
    expect(changeSet.removedSources, hasLength(equals(2)));
  }

  static void createChangeSet_onlyAdded() {
    AnalysisServer server = new AnalysisServer(
        new MockServerChannel(),
        PhysicalResourceProvider.INSTANCE);
    Request request = new Request('0', ContextDomainHandler.APPLY_CHANGES_NAME);
    ContextDomainHandler handler = new ContextDomainHandler(server);
    SourceFactory sourceFactory = new SourceFactory([new FileUriResolver()]);
    ChangeSet changeSet = handler.createChangeSet(request, sourceFactory,
        new RequestDatum(request, ContextDomainHandler.CHANGES_PARAM, {
      ContextDomainHandler.ADDED_PARAM: ['ffile:/one.dart'],
    }));
    expect(changeSet.addedSources, hasLength(equals(1)));
    expect(changeSet.changedSources, hasLength(equals(0)));
    expect(changeSet.removedSources, hasLength(equals(0)));
  }

  // TODO(scheglov) remove or move to the 'analysis' domain
//  static void setOptions() {
//    AnalysisServer server = new AnalysisServer(new MockServerChannel());
//    String contextId = _createContext(server);
//    Map<String, Object> options = new Map<String, Object>();
//    ContextDomainHandler handler = new ContextDomainHandler(server);
//
//    Request request = new Request('0', ContextDomainHandler.SET_OPTIONS_NAME);
//    request.setParameter(ContextDomainHandler.CONTEXT_ID_PARAM, contextId);
//    request.setParameter(ContextDomainHandler.OPTIONS_PARAM, options);
//    Response response = handler.handleRequest(request);
//    expect(response.toJson(), equals({
//      Response.ID: '0'
//    }));
//  }

  // TODO(scheglov) remove or move to the 'analysis' domain
//  static void setPrioritySources_empty() {
//    AnalysisServer server = new AnalysisServer(new MockServerChannel());
//    String contextId = _createContext(server);
//    List<String> sources = new List<String>();
//    ContextDomainHandler handler = new ContextDomainHandler(server);
//
//    Request request = new Request('0', ContextDomainHandler.SET_PRIORITY_SOURCES_NAME);
//    request.setParameter(ContextDomainHandler.CONTEXT_ID_PARAM, contextId);
//    request.setParameter(ContextDomainHandler.SOURCES_PARAM, sources);
//    Response response = handler.handleRequest(request);
//    expect(response.toJson(), equals({
//      Response.ID: '0'
//    }));
//  }

  // TODO(scheglov) remove or move to the 'analysis' domain
//  static void setPrioritySources_nonEmpty() {
//    AnalysisServer server = new AnalysisServer(new MockServerChannel());
//    String contextId = _createContext(server);
//    List<String> sources = new List<String>();
//    sources.add("foo.dart");
//    ContextDomainHandler handler = new ContextDomainHandler(server);
//
//    Request request = new Request('0', ContextDomainHandler.SET_PRIORITY_SOURCES_NAME);
//    request.setParameter(ContextDomainHandler.CONTEXT_ID_PARAM, contextId);
//    request.setParameter(ContextDomainHandler.SOURCES_PARAM, sources);
//    Response response = handler.handleRequest(request);
//    expect(response.toJson(), equals({
//      Response.ID: '0'
//    }));
//  }

  // TODO(scheglov) remove or move to the 'analysis' domain
//  static String _createContext(AnalysisServer server) {
//    String contextId = "context${contextIdCounter++}";
//    ServerDomainHandler handler = new ServerDomainHandler(server);
//    Request request = new Request('0', ServerDomainHandler.CREATE_CONTEXT_METHOD);
//    request.setParameter(ServerDomainHandler.SDK_DIRECTORY_PARAM, sdkPath);
//    request.setParameter(AnalysisServer.CONTEXT_ID_PARAM, contextId);
//    Response response = handler.handleRequest(request);
//    if (response.error != null) {
//      fail('Unexpected error: ${response.error.toJson()}');
//    }
//    return contextId;
//  }
}
