// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

library webdriver.support.forwarder;

import 'dart:async' show Future, StreamConsumer;
import 'dart:convert' show JSON, UTF8;
import 'dart:io' show ContentType, Directory, File, HttpRequest, HttpStatus;

import 'package:path/path.dart' as path;
import 'package:webdriver/core.dart'
    show By, WebDriver, WebDriverException, WebElement;

final _contentTypeJson =
    new ContentType('application', 'json', charset: 'utf-8');

/// Attribute on elements used to locate them on passed WebDriver commands.
const wdElementIdAttribute = 'wd-element-id';

/// [WebDriverForwarder] accepts [HttpRequest]s corresponding to a variation on
/// the WebDriver wire protocol and forwards them to a WebDriver instance.
///
/// The primary difference between this and the standard wire protocol is in
/// the use of WebElement ids. When you need to refer to an element in a request
/// (URI or JSON body), then you should add an 'wd-element-id' attribute to the
/// corresponding element with a unique identifier, and use that identifier as
/// the element id for that element. This class will then search for the
/// corresponding element and in the document and will substitute an actual
/// WebElement id for the given identifier in the request.
///
/// This forwarder supports two additional commands that control how it searches
/// for elements:
///   POST '/enabledeep': enables searching through all Shadow DOMs in the
///     document for the corresponding element (but will fail on browsers that
///     don't support the '/deep/' css selector combinator).
///   POST '/disabledeep': disables searching in Shadow DOMs of the document.
///
/// This forwarder also supports two additional commands for grabbing the
/// browser contents and saving it to the file system.
///   POST '/screenshot': takes a 'file' arg and will capture a screenshot
///     of the browser and save it to the specified file name in [outputDir].
///   POST '/source': takes a 'file' arg and will capture the current page's
///     source and save it to the specified file name in [outputDir].
///
/// See https://code.google.com/p/selenium/wiki/JsonWireProtocol for
/// documentation of other commands.
class WebDriverForwarder {
  /// [WebDriver] instance to forward commands to.
  final WebDriver driver;

  /// Path prefix that all forwarded commands will have.
  final Pattern prefix;

  /// Directory to save screenshots and page source to.
  final Directory outputDir;

  /// Search for elements in all shadow doms of the current document.
  bool useDeep;

  WebDriverForwarder(this.driver,
      {this.prefix: '/webdriver', Directory outputDir, this.useDeep: false})
      : this.outputDir = outputDir == null
            ? Directory.systemTemp.createTempSync()
            : outputDir;

  /// Forward [request] to [driver] and respond to the request with the returned
  /// value or any thrown exceptions.
  Future forward(HttpRequest request) async {
    try {
      if (!request.uri.path.startsWith(prefix)) {
        request.response.statusCode = HttpStatus.NOT_FOUND;
        return;
      }
      request.response.statusCode = HttpStatus.OK;
      request.response.headers.contentType = _contentTypeJson;

      var endpoint = request.uri.path.replaceFirst(prefix, '');
      if (endpoint.startsWith('/')) {
        endpoint = endpoint.substring(1);
      }
      var params;
      if (request.method == 'POST') {
        String requestBody = await UTF8.decodeStream(request);
        if (requestBody != null && requestBody.isNotEmpty) {
          params = JSON.decode(requestBody);
        }
      }
      var value = await _forward(request.method, endpoint, params);
      request.response
          .add(UTF8.encode(JSON.encode({'status': 0, 'value': value})));
    } on WebDriverException catch (e) {
      request.response.add(UTF8.encode(JSON.encode({
        'status': e.statusCode,
        'value': {'message': e.message}
      })));
    } catch (e) {
      request.response.add(UTF8.encode(JSON.encode({
        'status': 13,
        'value': {'message': e.toString()}
      })));
    } finally {
      await request.response.close();
    }
  }

  Future _forward(String method, String endpoint,
      [Map<String, dynamic> params]) async {
    List<String> endpointTokens = path.split(endpoint);
    if (endpointTokens.isEmpty) {
      endpointTokens = [''];
    }
    switch (endpointTokens[0]) {
      case 'enabledeep':
        // turn on Shadow DOM support, don't forward
        useDeep = true;
        return null;
      case 'disabledeep':
        // turn off Shadow DOM support, don't forward
        useDeep = false;
        return null;
      case 'screenshot':
        if (method == 'POST') {
          // take a screenshot and save to file system
          var file =
              new File(path.join(outputDir.path, params['file'])).openWrite();
          await driver.captureScreenshot().map((b) => [b]).pipe(file);
          return null;
        }
        break;
      case 'source':
        if (method == 'POST') {
          // grab page source and save to file system
          await new File(path.join(outputDir.path, params['file']))
              .writeAsString(await driver.pageSource);
          return null;
        }
        break;
      case 'element':
        // process endpoints of the form /element/[id]/...
        if (endpointTokens.length >= 2) {
          endpointTokens[1] = await _findElement(endpointTokens[1]);
        }
        // process endpoint /element/[id]/equals/[id]
        if (endpointTokens.length == 4 && endpointTokens[2] == 'equals') {
          endpointTokens[3] = await _findElement(endpointTokens[3]);
        }
        break;
      case 'touch':
      case 'moveto':
        // several /touch/... endpoints and the /moveto endpoint have an
        // optional 'element' param with a WebElement id value
        if (params['element'] != null) {
          params = new Map.from(params);
          params['element'] = await _findElement(params['element']);
        }
        break;
      case 'execute':
      case 'execute_async':
        // /execute and /execute_async allow arbitrary JSON objects with
        // embedded WebElememt ids.
        params = await _deepCopy(params);
        break;
    }

    switch (method) {
      case 'GET':
        return await driver.getRequest(path.joinAll(endpointTokens));
      case 'DELETE':
        return await driver.deleteRequest(path.joinAll(endpointTokens));
      case 'POST':
        return await driver.postRequest(path.joinAll(endpointTokens), params);
      default:
        throw 'unsupported method $method';
    }
  }

  Future<String> _findElement(String id) async {
    var selector = "[$wdElementIdAttribute='$id']";
    if (useDeep) {
      selector = '* /deep/ $selector';
    }
    var elements =
        await driver.findElements(new By.cssSelector(selector)).toList();
    return elements.single.id;
  }

  dynamic _deepCopy(dynamic source) async {
    if (source is Map) {
      var copy = {};

      for (var key in source.keys) {
        var value = source[key];
        if (key == 'ELEMENT') {
          copy['ELEMENT'] = await _findElement(value);
        } else {
          copy[await _deepCopy(key)] = await _deepCopy(value);
        }
      }
      return copy;
    } else if (source is Iterable) {
      var copy = [];
      for (var value in source) {
        copy.add(await _deepCopy(value));
      }
      return copy;
    } else {
      return source;
    }
  }
}
