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

library input.transformer.instrumentation;

import 'dart:convert';

import 'package:analyzer/src/generated/java_engine.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 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;
  }
}
