// Copyright (c) 2015, 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:analyzer/exception/exception.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:logging/logging.dart';

import 'input_converter.dart';
import 'operation.dart';

final int COLON = ':'.codeUnitAt(0);

/**
 * [InstrumentationInputConverter] converts an instrumentation stream
 * into a series of operations to be sent to the analysis server.
 */
class InstrumentationInputConverter extends CommonInputConverter {
  final Set<String> codesSeen = new Set<String>();

  /**
   * [readBuffer] holds the contents of the file being read from disk
   * as recorded in the instrumentation log
   * or `null` if not converting a "Read" entry.
   */
  StringBuffer readBuffer = null;

  InstrumentationInputConverter(String tmpSrcDirPath, PathMap srcPathMap)
      : super(tmpSrcDirPath, srcPathMap);

  @override
  Operation convert(String line) {
    List<String> fields;
    try {
      fields = _parseFields(line);
      if (fields.length < 2) {
        if (readBuffer != null) {
          readBuffer.writeln(fields.length == 1 ? fields[0] : '');
          return null;
        }
        throw 'Failed to process line:\n$line';
      }
      if (readBuffer != null) {
        readBuffer = null;
      }
    } catch (e, s) {
      throw new AnalysisException(
          'Failed to parse line\n$line', new CaughtException(e, s));
    }
    // int timeStamp = int.parse(fields[0], onError: (_) => -1);
    String opCode = fields[1];
    if (opCode == InstrumentationService.TAG_NOTIFICATION) {
      return convertNotification(decodeJson(line, fields[2]));
    } else if (opCode == 'Read') {
      // 1434096943209:Read:/some/file/path:1434095535000:<file content>
      //String filePath = fields[2];
      readBuffer = new StringBuffer(fields.length > 4 ? fields[4] : '');
      return null;
    } else if (opCode == InstrumentationService.TAG_REQUEST) {
      return convertRequest(decodeJson(line, fields[2]));
    } else if (opCode == InstrumentationService.TAG_RESPONSE) {
      // 1434096937454:Res:{"id"::"0","result"::{"version"::"1.7.0"}}
      return convertResponse(decodeJson(line, fields[2]));
    } else if (opCode == InstrumentationService.TAG_ANALYSIS_TASK) {
      // 1434096943208:Task:/Users/
      return null;
    } else if (opCode == InstrumentationService.TAG_LOG_ENTRY) {
      // 1434096937454:Res:{"id"::"0","result"::{"version"::"1.7.0"}}
      return null;
    } else if (opCode == InstrumentationService.TAG_PERFORMANCE) {
      //1434096960092:Perf:analysis_full:16884:context_id=0
      return null;
    } else if (opCode == InstrumentationService.TAG_SUBPROCESS_START) {
      // 1434096938634:SPStart:0:/Users/da
      return null;
    } else if (opCode == InstrumentationService.TAG_SUBPROCESS_RESULT) {
      // 1434096939068:SPResult:0:0:"{\"packages\"::{\"rpi_lidar\"::\"/Users
      return null;
    } else if (opCode == InstrumentationService.TAG_VERSION) {
      // 1434096937358:Ver:1421765742287333878467:org.dartlang.dartplugin
      return null;
    } else if (opCode == InstrumentationService.TAG_WATCH_EVENT) {
      // 1434097460414:Watch:/some/file/path
      return null;
    }
    if (codesSeen.add(opCode)) {
      logger.log(
          Level.WARNING, 'Ignored instrumentation op code: $opCode\n  $line');
    }
    return null;
  }

  Map<String, dynamic> decodeJson(String line, String text) {
    try {
      return asMap(json.decode(text));
    } catch (e, s) {
      throw new AnalysisException(
          'Failed to decode JSON: $text\n$line', new CaughtException(e, s));
    }
  }

  /**
   * Determine if the given line is from an instrumentation file.
   * For example:
   * `1433175833005:Ver:1421765742287333878467:org.dartlang.dartplugin:0.0.0:1.6.2:1.11.0-edge.131698`
   */
  static bool isFormat(String line) {
    List<String> fields = _parseFields(line);
    if (fields.length < 2) return false;
    int timeStamp = int.parse(fields[0], onError: (_) => -1);
    String opCode = fields[1];
    return timeStamp > 0 && opCode == 'Ver';
  }

  /**
   * Extract fields from the given [line].
   */
  static List<String> _parseFields(String line) {
    List<String> fields = new List<String>();
    int index = 0;
    StringBuffer sb = new StringBuffer();
    while (index < line.length) {
      int code = line.codeUnitAt(index);
      if (code == COLON) {
        // Embedded colons are doubled
        int next = index + 1;
        if (next < line.length && line.codeUnitAt(next) == COLON) {
          sb.write(':');
          ++index;
        } else {
          fields.add(sb.toString());
          sb.clear();
        }
      } else {
        sb.writeCharCode(code);
      }
      ++index;
    }
    if (sb.isNotEmpty) {
      fields.add(sb.toString());
    }
    return fields;
  }
}
