// Copyright 2020 Garett Tok Ern Liang
//
// 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
//
//     https://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.

import 'package:yaml/yaml.dart';

import 'editor.dart';
import 'source_edit.dart';
import 'strings.dart';
import 'utils.dart';
import 'wrap.dart';

/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
/// the effect of setting the element at [index] to [newValue] when re-parsed.
SourceEdit updateInList(
    YamlEditor yamlEdit, YamlList list, int index, YamlNode newValue) {
  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
  ArgumentError.checkNotNull(list, 'list');
  RangeError.checkValueInInterval(index, 0, list.length - 1);

  final currValue = list.nodes[index];
  final offset = currValue.span.start.offset;
  final yaml = yamlEdit.toString();
  String valueString;

  /// We do not use [_formatNewBlock] since we want to only replace the contents
  /// of this node while preserving comments/whitespace, while [_formatNewBlock]
  /// produces a string represnetation of a new node.
  if (list.style == CollectionStyle.BLOCK) {
    final listIndentation = getListIndentation(yaml, list);
    final indentation = listIndentation + getIndentation(yamlEdit);
    final lineEnding = getLineEnding(yaml);
    valueString = yamlEncodeBlockString(
        wrapAsYamlNode(newValue), indentation, lineEnding);

    /// We prefer the compact nested notation for collections.
    ///
    /// By virtue of [yamlEncodeBlockString], collections automatically
    /// have the necessary line endings.
    if ((newValue is List && (newValue as List).isNotEmpty) ||
        (newValue is Map && (newValue as Map).isNotEmpty)) {
      valueString = valueString.substring(indentation);
    } else if (isCollection(currValue) &&
        getStyle(currValue) == CollectionStyle.BLOCK) {
      valueString += lineEnding;
    }

    final end = getContentSensitiveEnd(currValue);

    return SourceEdit(offset, end - offset, valueString);
  } else {
    valueString = yamlEncodeFlowString(newValue);
    return SourceEdit(offset, currValue.span.length, valueString);
  }
}

/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
/// the effect of appending [item] to the list.
SourceEdit appendIntoList(YamlEditor yamlEdit, YamlList list, YamlNode item) {
  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
  ArgumentError.checkNotNull(list, 'list');

  if (list.style == CollectionStyle.FLOW) {
    return _appendToFlowList(yamlEdit, list, item);
  } else {
    return _appendToBlockList(yamlEdit, list, item);
  }
}

/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
/// the effect of inserting [item] to the list at [index].
SourceEdit insertInList(
    YamlEditor yamlEdit, YamlList list, int index, YamlNode item) {
  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
  ArgumentError.checkNotNull(list, 'list');
  RangeError.checkValueInInterval(index, 0, list.length);

  /// We call the append method if the user wants to append it to the end of the
  /// list because appending requires different techniques.
  if (index == list.length) {
    return appendIntoList(yamlEdit, list, item);
  } else {
    if (list.style == CollectionStyle.FLOW) {
      return _insertInFlowList(yamlEdit, list, index, item);
    } else {
      return _insertInBlockList(yamlEdit, list, index, item);
    }
  }
}

/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
/// the effect of removing the element at [index] when re-parsed.
SourceEdit removeInList(YamlEditor yamlEdit, YamlList list, int index) {
  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
  ArgumentError.checkNotNull(list, 'list');

  final nodeToRemove = list.nodes[index];

  if (list.style == CollectionStyle.FLOW) {
    return _removeFromFlowList(yamlEdit, list, nodeToRemove, index);
  } else {
    return _removeFromBlockList(yamlEdit, list, nodeToRemove, index);
  }
}

/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
/// the effect of addition [item] into [nodes], noting that this is a flow list.
SourceEdit _appendToFlowList(
    YamlEditor yamlEdit, YamlList list, YamlNode item) {
  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
  ArgumentError.checkNotNull(list, 'list');

  final valueString = _formatNewFlow(list, item, true);
  return SourceEdit(list.span.end.offset - 1, 0, valueString);
}

/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
/// the effect of addition [item] into [nodes], noting that this is a block list.
SourceEdit _appendToBlockList(
    YamlEditor yamlEdit, YamlList list, YamlNode item) {
  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
  ArgumentError.checkNotNull(list, 'list');

  var formattedValue = _formatNewBlock(yamlEdit, list, item);
  final yaml = yamlEdit.toString();
  var offset = list.span.end.offset;

  // Adjusts offset to after the trailing newline of the last entry, if it exists
  if (list.isNotEmpty) {
    final lastValueSpanEnd = list.nodes.last.span.end.offset;
    final nextNewLineIndex = yaml.indexOf('\n', lastValueSpanEnd);
    if (nextNewLineIndex == -1) {
      formattedValue = getLineEnding(yaml) + formattedValue;
    } else {
      offset = nextNewLineIndex + 1;
    }
  }

  return SourceEdit(offset, 0, formattedValue);
}

/// Formats [item] into a new node for block lists.
String _formatNewBlock(YamlEditor yamlEdit, YamlList list, YamlNode item) {
  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
  ArgumentError.checkNotNull(list, 'list');

  final yaml = yamlEdit.toString();
  final listIndentation = getListIndentation(yaml, list);
  final newIndentation = listIndentation + getIndentation(yamlEdit);
  final lineEnding = getLineEnding(yaml);

  var valueString = yamlEncodeBlockString(item, newIndentation, lineEnding);
  if (isCollection(item) && !isFlowYamlCollectionNode(item) && !isEmpty(item)) {
    valueString = valueString.substring(newIndentation);
  }
  final indentedHyphen = ' ' * listIndentation + '- ';

  return '$indentedHyphen$valueString$lineEnding';
}

/// Formats [item] into a new node for flow lists.
String _formatNewFlow(YamlList list, YamlNode item, [bool isLast = false]) {
  ArgumentError.checkNotNull(list, 'list');
  ArgumentError.checkNotNull(isLast, 'isLast');

  var valueString = yamlEncodeFlowString(item);
  if (list.isNotEmpty) {
    if (isLast) {
      valueString = ', $valueString';
    } else {
      valueString += ', ';
    }
  }

  return valueString;
}

/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
/// the effect of inserting [item] into [nodes] at [index], noting that this is
/// a block list.
///
/// [index] should be non-negative and less than or equal to [length].
SourceEdit _insertInBlockList(
    YamlEditor yamlEdit, YamlList list, int index, YamlNode item) {
  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
  ArgumentError.checkNotNull(list, 'list');
  RangeError.checkValueInInterval(index, 0, list.length);

  if (index == list.length) return _appendToBlockList(yamlEdit, list, item);

  final formattedValue = _formatNewBlock(yamlEdit, list, item);

  final currNode = list.nodes[index];
  final currNodeStart = currNode.span.start.offset;
  final yaml = yamlEdit.toString();
  final start = yaml.lastIndexOf('\n', currNodeStart) + 1;

  return SourceEdit(start, 0, formattedValue);
}

/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
/// the effect of inserting [item] into [nodes] at [index], noting that this is
/// a flow list.
///
/// [index] should be non-negative and less than or equal to [length].
SourceEdit _insertInFlowList(
    YamlEditor yamlEdit, YamlList list, int index, YamlNode item) {
  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
  ArgumentError.checkNotNull(list, 'list');
  RangeError.checkValueInInterval(index, 0, list.length);

  if (index == list.length) return _appendToFlowList(yamlEdit, list, item);

  final formattedValue = _formatNewFlow(list, item);

  final yaml = yamlEdit.toString();
  final currNode = list.nodes[index];
  final currNodeStart = currNode.span.start.offset;
  var start = yaml.lastIndexOf(RegExp(r',|\['), currNodeStart - 1) + 1;
  if (yaml[start] == ' ') start++;

  return SourceEdit(start, 0, formattedValue);
}

/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
/// the effect of removing [nodeToRemove] from [nodes], noting that this is a
/// block list.
///
/// [index] should be non-negative and less than or equal to [length].
SourceEdit _removeFromBlockList(
    YamlEditor yamlEdit, YamlList list, YamlNode nodeToRemove, int index) {
  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
  ArgumentError.checkNotNull(list, 'list');
  RangeError.checkValueInInterval(index, 0, list.length - 1);

  /// If we are removing the last element in a block list, convert it into a
  /// flow empty list.
  if (list.length == 1) {
    final start = list.span.start.offset;
    final end = getContentSensitiveEnd(nodeToRemove);

    return SourceEdit(start, end - start, '[]');
  }

  final yaml = yamlEdit.toString();
  final span = nodeToRemove.span;

  /// The general removal strategy is to remove everything that starts from
  /// [nodeToRemove]'s dash to the next node's dash.
  ///
  /// -1 accounts for the fact that the content can start with a dash
  var start = yaml.lastIndexOf('-', span.start.offset - 1);
  var end = yaml.lastIndexOf('\n', list.span.end.offset) + 1;

  if (index < list.length - 1) {
    final nextNode = list.nodes[index + 1];
    end = yaml.lastIndexOf('-', nextNode.span.start.offset - 1);
  } else {
    /// If there is a possibility that there is a `-` or `\n` before the node
    if (start > 0) {
      final lastHyphen = yaml.lastIndexOf('-', start - 1);
      final lastNewLine = yaml.lastIndexOf('\n', start - 1);
      if (lastHyphen > lastNewLine) {
        start = lastHyphen + 2;
      } else if (lastNewLine > lastHyphen) {
        start = lastNewLine + 1;
      }
    }
  }

  return SourceEdit(start, end - start, '');
}

/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
/// the effect of removing [nodeToRemove] from [nodes], noting that this is a
/// flow list.
///
/// [index] should be non-negative and less than or equal to [length].
SourceEdit _removeFromFlowList(
    YamlEditor yamlEdit, YamlList list, YamlNode nodeToRemove, int index) {
  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
  ArgumentError.checkNotNull(list, 'list');
  RangeError.checkValueInInterval(index, 0, list.length - 1);

  final span = nodeToRemove.span;
  final yaml = yamlEdit.toString();
  var start = span.start.offset;
  var end = span.end.offset;

  if (index == 0) {
    start = yaml.lastIndexOf('[', start - 1) + 1;
    if (index == list.length - 1) {
      end = yaml.indexOf(']', end);
    } else {
      end = yaml.indexOf(',', end) + 1;
    }
  } else {
    start = yaml.lastIndexOf(',', start - 1);
  }

  return SourceEdit(start, end - start, '');
}
