content: package in.oneton.idea.spring.assistant.plugin.suggestion.handler;
  
  import com.intellij.codeInsight.completion.InsertHandler;
  import com.intellij.codeInsight.completion.InsertionContext;
  import com.intellij.codeInsight.lookup.LookupElement;
  import com.intellij.util.text.CharArrayUtil;
  import org.apache.commons.lang.StringUtils;
  
  // a large section of this class is borrowed from https://github.com/zalando/intellij-swagger
  public class YamlValueInsertHandler implements InsertHandler<LookupElement> {
  
    private static final char SINGLE_QUOTE = '\'';
    private static final char DOUBLE_QUOTE = '"';
  
    private static final char[] RESERVED_YAML_CHARS =
        {':', '{', '}', '[', ']', ',', '&', '*', '#', '?', '|', '-', '<', '>', '=', '!', '%', '@',
            '`'};
  
    public static String unescapeValue(String value) {
      return value.replaceAll("^['\"]", "").replaceAll("['\"]$", "");
    }
  
    @Override
    public void handleInsert(final InsertionContext insertionContext,
        final LookupElement lookupElement) {
      if (shouldUseQuotes(lookupElement)) {
        final boolean hasDoubleQuotes =
            hasStartingOrEndingQuoteOfType(insertionContext, lookupElement, DOUBLE_QUOTE);
  
        if (hasDoubleQuotes) {
          handleEndingQuote(insertionContext, DOUBLE_QUOTE);
          handleStartingQuote(insertionContext, lookupElement, DOUBLE_QUOTE);
        } else {
          handleEndingQuote(insertionContext, SINGLE_QUOTE);
          handleStartingQuote(insertionContext, lookupElement, SINGLE_QUOTE);
        }
      }
    }
  
    private boolean shouldUseQuotes(final LookupElement lookupElement) {
      return StringUtils.containsAny(lookupElement.getLookupString(), RESERVED_YAML_CHARS);
    }
  
    private boolean hasStartingOrEndingQuoteOfType(final InsertionContext insertionContext,
        final LookupElement lookupElement, final char quoteType) {
      final int caretOffset = insertionContext.getEditor().getCaretModel().getOffset();
      final int startOfLookupStringOffset = caretOffset - lookupElement.getLookupString().length();
  
  
      final boolean hasStartingQuote =
          hasStartingQuote(insertionContext, quoteType, startOfLookupStringOffset);
      final boolean hasEndingQuote = hasEndingQuote(insertionContext, caretOffset, quoteType);
  
      return hasStartingQuote || hasEndingQuote;
    }
  
    private boolean hasEndingQuote(final InsertionContext insertionContext, final int caretOffset,
        final char quoteType) {
      final CharSequence chars = insertionContext.getDocument().getCharsSequence();
  
      return CharArrayUtil.regionMatches(chars, caretOffset, String.valueOf(quoteType));
    }
  
    private boolean hasStartingQuote(final InsertionContext insertionContext, final char quoteType,
        final int startOfLookupStringOffset) {
      return insertionContext.getDocument().getText().charAt(startOfLookupStringOffset - 1)
          == quoteType;
    }
  
    private void handleStartingQuote(final InsertionContext insertionContext,
        final LookupElement lookupElement, final char quoteType) {
      final int caretOffset = insertionContext.getEditor().getCaretModel().getOffset();
      final int startOfLookupStringOffset = caretOffset - lookupElement.getLookupString().length();
  
      final boolean hasStartingQuote =
          hasStartingQuote(insertionContext, quoteType, startOfLookupStringOffset);
  
      if (!hasStartingQuote) {
        insertionContext.getDocument()
            .insertString(startOfLookupStringOffset, String.valueOf(quoteType));
      }
    }
  
    private void handleEndingQuote(final InsertionContext insertionContext, final char quoteType) {
      final int caretOffset = insertionContext.getEditor().getCaretModel().getOffset();
  
      final boolean hasEndingQuote = hasEndingQuote(insertionContext, caretOffset, quoteType);
  
      if (!hasEndingQuote) {
        insertionContext.getDocument().insertString(caretOffset, String.valueOf(quoteType));
      }
    }
  }
  