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

import 'dart:async' show Future, Stream, StreamController;
import 'dart:convert' show Encoding, JSON;
import 'dart:io' show exit, Stdin, stdin, SYSTEM_ENCODING;

import 'package:webdriver/src/stepper.dart';

LineReader _stdinLineReader;

/// A [LineReader] instance connected to 'dart:io' [stdin].
LineReader get stdinLineReader {
  if (_stdinLineReader == null) {
    _stdinLineReader = new LineReader(stdin);
  }
  return _stdinLineReader;
}

/// Provides a command line interface for stepping through or skipping
/// WebDriver commands.
class StdioStepper implements Stepper {
  bool enabled = true;

  final LineReader _reader;

  StdioStepper({LineReader reader})
      : _reader = reader == null ? stdinLineReader : reader;

  @override
  Future<bool> step(String method, String command, params) async {
    if (!enabled) return true;
    print('$method $command(${JSON.encode(params)}):');
    await for (String command in _reader.onLine) {
      switch (command) {
        case 'continue':
        case 'c':
          return true;
        case 'skip':
        case 's':
          return false;
        case 'break':
        case 'b':
          throw new Exception('process ended by user.');
        case 'help':
        case 'h':
          _printUsage();
          break;
        case 'disable':
        case 'd':
          enabled = false;
          return true;
        case 'quit':
        case 'q':
          exit(-1);
          return false;
        default:
          print('invalid command: `$command` enter `h` or `help` for help.');
      }
    }
    throw new Exception('stdin has been closed');
  }

  _printUsage() {
    print('`c` or `continue`: execute command');
    print('`s` or `skip`: skip command');
    print('`d` or `disable`: disable stepper');
    print('`b` or `break`: throw exception');
    print('`q` or `quit`: terminate vm');
    print('`h` or `help`: display this message');
  }
}

/// Converts a Stream<List<int> | int> to Stream<String> that fires an event
/// for every line of data in the original Stream.
class LineReader {
  static const CR = 13;
  static const LF = 10;

  bool _crPrevious = false;
  final _bytes = <int>[];
  final _controller = new StreamController<String>.broadcast();

  final Encoding encoding;

  /// Only encodings that are a superset of ASCII are supported
  /// TODO(DrMarcII): Support arbitrary encodings
  LineReader(Stream /* <List<int> | int> */ stream,
      {this.encoding: SYSTEM_ENCODING}) {
    if (stream is Stdin) {
      stdin.lineMode = false;
    }
    stream.listen(_listen,
        onDone: _controller.close, onError: _controller.addError);
  }

  void _listen(/* List<int> | int */ data) {
    if (data is List) {
      data.forEach(_addByte);
    } else {
      _addByte(data);
    }
  }

  void _addByte(int byte) {
    if (_crPrevious && byte == LF) {
      _crPrevious = false;
      return;
    }
    _crPrevious = byte == CR;
    if (byte == CR || byte == LF) {
      _controller.add(encoding.decode(_bytes));
      _bytes.clear();
    } else {
      _bytes.add(byte);
    }
  }

  /// A Stream that fires for each line of data.
  Stream<String> get onLine => _controller.stream;
}
