// 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 dart2js.serialization.json;

import 'dart:convert';
import 'keys.dart';
import 'serialization.dart';
import 'values.dart';

/// Serialization encoder for JSON.
class JsonSerializationEncoder implements SerializationEncoder {
  const JsonSerializationEncoder();

  String encode(ObjectValue objectValue) {
    return new JsonEncoder.withIndent(' ').convert(
        const JsonValueEncoder().convert(objectValue));
  }
}

/// Serialization decoder for JSON.
class JsonSerializationDecoder implements SerializationDecoder {
  const JsonSerializationDecoder();

  Map decode(String text) => JSON.decode(text);

  /// Returns the name of the [key] which used for to store a [Key] into a
  /// [Map]; corresponding to the encoding of object properties in
  /// [JsonValueEncoder.visitObject].
  getObjectPropertyValue(Key key) => key.name;
}

/// A [ValueVisitor] that computes a JSON object value.
class JsonValueEncoder implements ValueVisitor {
  const JsonValueEncoder();

  convert(Value value) => visit(value, null);

  @override
  visit(Value value, [arg]) => value.accept(this, arg);

  @override
  bool visitBool(BoolValue value, arg) => value.value;

  @override
  visitConstant(ConstantValue value, arg) => visit(value.id);

  @override
  double visitDouble(DoubleValue value, arg) => value.value;

  @override
  visitElement(ElementValue value, arg) => visit(value.id);

  @override
  visitEnum(EnumValue value, arg) => value.value.index;

  @override
  int visitInt(IntValue value, arg) => value.value;

  @override
  List visitList(ListValue value, arg) => value.values.map(visit).toList();

  @override
  Map visitMap(MapValue value, arg) {
    Map<String, dynamic> map = <String, dynamic>{};
    value.map.forEach((String key, Value value) {
      map[key] = visit(value);
    });
    return map;
  }

  @override
  Map visitObject(ObjectValue value, arg) {
    Map<String, dynamic> map = <String, dynamic>{};
    value.map.forEach((Key key, Value value) {
      map[key.name] = visit(value);
    });
    return map;
  }

  @override
  String visitString(StringValue value, arg) => value.value;

  @override
  visitType(TypeValue value, arg) => visit(value.id);

  @override
  visitUri(UriValue value, arg) => '${value.value}';
}

/// [ValueVisitor] that generates a verbose JSON-like output.
class PrettyPrintEncoder implements ValueVisitor {
  StringBuffer buffer;

  String toText(Value value) {
    buffer = new StringBuffer();
    visit(value, '');
    String text = buffer.toString();
    buffer = null;
    return text;
  }

  @override
  void visit(Value value, String indentation) {
    value.accept(this, indentation);
  }

  @override
  void visitBool(BoolValue value, String indentation) {
    buffer.write(value.value);
  }

  @override
  void visitConstant(ConstantValue value, String indentation) {
    buffer.write('Constant(${value.id}):${value.constant.getText()}');
  }

  @override
  void visitDouble(DoubleValue value, String indentation) {
    buffer.write(value.value);
  }
  @override
  void visitElement(ElementValue value, String indentation) {
    buffer.write('Element(${value.id}):${value.element}');
  }

  @override
  void visitEnum(EnumValue value, String indentation) {
    buffer.write(value.value);
  }

  @override
  void visitInt(IntValue value, String indentation) {
    buffer.write(value.value);
  }

  @override
  void visitList(ListValue value, String indentation) {
    if (value.values.isEmpty) {
      buffer.write('[]');
    } else {
      buffer.write('[');
      bool needsComma = false;
      String nextIndentation = '${indentation}  ';
      for (Value element in value.values) {
        if (needsComma) {
          buffer.write(',');
        }
        buffer.write('\n$nextIndentation');
        visit(element, nextIndentation);
        needsComma = true;
      }
      buffer.write('\n$indentation]');
    }
  }

  @override
  void visitMap(MapValue value, String indentation) {
    if (value.map.isEmpty) {
      buffer.write('{}');
    } else {
      buffer.write('{');
      bool needsComma = false;
      String nextIndentation = '${indentation}  ';
      value.map.forEach((String key, Value subvalue) {
        if (needsComma) {
          buffer.write(',');
        }
        buffer.write('\n$nextIndentation$key: ');
        visit(subvalue, nextIndentation);
        needsComma = true;
      });
      buffer.write('\n$indentation}');
    }
  }

  @override
  void visitObject(ObjectValue value, String indentation) {
    if (value.map.isEmpty) {
      buffer.write('{}');
    } else {
      buffer.write('{');
      bool needsComma = false;
      String nextIndentation = '${indentation}  ';
      value.map.forEach((Key key, Value subvalue) {
        if (needsComma) {
          buffer.write(',');
        }
        buffer.write('\n$nextIndentation$key: ');
        visit(subvalue, nextIndentation);
        needsComma = true;
      });
      buffer.write('\n$indentation}');
    }
  }

  @override
  void visitString(StringValue value, String indentation) {
    buffer.write('"${value.value}"');
  }

  @override
  void visitType(TypeValue value, String indentation) {
    buffer.write('Type(${value.id}):${value.type}');
  }

  @override
  void visitUri(UriValue value, String indentation) {
    buffer.write('Uri(${value.value})');
  }
}