/*
 * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation
//
package org.eclipse.persistence.jpa.jpql.tools;

import java.util.LinkedList;
import java.util.List;
import org.eclipse.persistence.jpa.jpql.Assert;
import org.eclipse.persistence.jpa.jpql.utility.iterable.ListIterable;
import org.eclipse.persistence.jpa.jpql.utility.iterable.SnapshotCloneListIterable;

/**
 * The default implementation of {@link RefactoringDelta} which contains the {@link TextEdit} that
 * were creating during the refactoring of a JPQL query.
 *
 * @version 2.5
 * @since 2.4
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public class DefaultRefactoringDelta implements RefactoringDelta {

    /**
     * The JPQL query or JPQL fragment that will be traversed when refactoring operations will be executed.
     */
    private CharSequence jpqlQuery;

    /**
     * The list of {@link TextEdit} objects that have been added by refactoring operations.
     */
    private List<TextEdit> textEdits;

    /**
     * Creates a new <code>DefaultRefactoringDelta</code>.
     *
     * @param jpqlQuery The JPQL query or JPQL fragment that will be traversed when refactoring
     * operations will be executed
     * @exception NullPointerException The JPQL query cannot be <code>null</code>
     */
    public DefaultRefactoringDelta(CharSequence jpqlQuery) {
        super();
        initialize(jpqlQuery);
    }

    /**
     * Adds the given {@link TextEdit} at the right position. The list will be kept ordered, meaning
     * the insertion index is based on the offset, from the biggest value to the smallest value.
     *
     * @param textEdit The {@link TextEdit} to add
     * @exception NullPointerException The {@link TextEdit} cannot be <code>null</code>
     */
    public void addTextEdit(TextEdit textEdit) {

        Assert.isNotNull(textEdit, "The TextEdit cannot be null");

        if (textEdits.isEmpty()) {
            textEdits.add(textEdit);
        }
        else {
            int position = calculateInsertionPosition(textEdit);
            textEdits.add(position, textEdit);
        }
    }

    /**
     * Adds the given collection of {@link TextEdit} objects. The list will be kept ordered, meaning
     * the insertion index is based on the offset, from the biggest value to the smallest value.
     *
     * @param textEdits The collection of {@link TextEdit} objects to add
     * @exception NullPointerException The given {@link Iterable} or one of the child {@link TextEdit}
     * was <code>null</code>
     */
    public void addTextEdits(Iterable<? extends TextEdit> textEdits) {
        Assert.isNotNull(textEdits, "The Iterable<TextEdit> cannot be null");
        for (TextEdit textEdit : textEdits) {
            addTextEdit(textEdit);
        }
    }

    @Override
    public String applyChanges() {

        // Nothing to apply
        if (textEdits.isEmpty()) {
            return jpqlQuery.toString();
        }

        StringBuilder result = new StringBuilder(jpqlQuery);

        // The TextEdits are already in the right order (biggest offset to smallest offset),
        // so simply iterate them in order and replace the segments
        for (int index = 0, count = size(); index < count; index++) {
            TextEdit textEdit = textEdits.get(index);
            int offset = textEdit.getOffset();
            result.replace(offset, offset + textEdit.getLength(), textEdit.getNewValue());
        }

        textEdits.clear();
        return result.toString();
    }

    /**
     * Calculates the insertion position for the given {@link TextEdit} based on those already registered
     *
     * @param textEdit The {@link TextEdit} for which its insertion position will be calculated
     * @return The insertion position for the given {@link TextEdit}
     */
    protected int calculateInsertionPosition(TextEdit textEdit) {

        int position = size();

        for (int index = position; --index >= 0; ) {
            TextEdit edit = textEdits.get(index);
            if (textEdit.getOffset() > edit.getOffset()) {
                position = index;
            }
            else {
                break;
            }
        }

        return position;
    }

    @Override
    public boolean hasTextEdits() {
        return !textEdits.isEmpty();
    }

    /**
     * Initializes this <code>DefaultRefactoringDelta</code>.
     *
     * @param jpqlQuery The JPQL query or JPQL fragment that will be traversed when refactoring
     * operations will be executed
     * @exception NullPointerException The JPQL query cannot be <code>null</code>
     */
    protected void initialize(CharSequence jpqlQuery) {
        Assert.isNotNull(jpqlQuery, "The JPQL query cannot be null");
        this.jpqlQuery = jpqlQuery;
        this.textEdits = new LinkedList<TextEdit>();
    }

    @Override
    public int size() {
        return textEdits.size();
    }

    @Override
    public ListIterable<TextEdit> textEdits() {
        return new SnapshotCloneListIterable<TextEdit>(textEdits);
    }

    @Override
    public String toString() {
        return textEdits.toString();
    }
}
