/*******************************************************************************
 * Copyright (C) 2022, 1C-Soft LLC and others.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     1C-Soft LLC - initial API and implementation
 *******************************************************************************/
package com.e1c.v8codestyle.bsl.ui.qfix;

import java.util.Optional;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.link.LinkedModeModel;
import org.eclipse.jface.text.link.LinkedPosition;
import org.eclipse.jface.text.link.LinkedPositionGroup;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.ui.editor.model.IXtextDocument;

import com._1c.g5.v8.dt.bsl.model.Method;
import com._1c.g5.v8.dt.bsl.model.StaticFeatureAccess;
import com._1c.g5.v8.dt.bsl.ui.quickfix.BslQuickFixUtil;
import com._1c.g5.v8.dt.metadata.mdclass.ScriptVariant;
import com.e1c.g5.v8.dt.bsl.check.qfix.IXtextBslModuleFixModel;
import com.e1c.g5.v8.dt.bsl.check.qfix.IXtextInteractiveBslModuleFixModel;
import com.e1c.g5.v8.dt.bsl.check.qfix.SingleVariantXtextBslModuleFix;
import com.e1c.g5.v8.dt.check.qfix.components.QuickFix;

/**
 * Quick fix for check com.e1c.v8codestyle.bsl.check:undefined-variable
 *
 * @author Vadim Geraskin
 */
@QuickFix(checkId = "module-undefined-variable", supplierId = "com.e1c.v8codestyle.bsl")
public class UndefinedVariableFix
    extends SingleVariantXtextBslModuleFix
{
    @Override
    protected void configureFix(FixConfigurer configurer)
    {
        configurer.interactive(true)
            .description(Messages.UndefinedVariableFix_title)
            .details(Messages.UndefinedVariableFix_desc);
    }

    @Override
    protected TextEdit fixIssue(XtextResource state, IXtextBslModuleFixModel model) throws BadLocationException
    {
        IXtextInteractiveBslModuleFixModel interactiveModel = (IXtextInteractiveBslModuleFixModel)model;

        EObject element = model.getElement();
        String declarationKeyWord = getDeclarationKeyword(model);

        //up to Method class
        Method method = EcoreUtil2.getContainerOfType(element, Method.class);

        if (method != null)
        {
            Optional<String> indent = interactiveModel.getFormatString(method);
            if (indent.isPresent())
            {
                int offset = QuickFixMethodsHelper.getMethodOffset(method);

                String variableName = ((StaticFeatureAccess)model.getElement()).getName();
                IXtextDocument document = (IXtextDocument)interactiveModel.getDocument();
                String lineSeparator = model.getLineSeparator();

                String variable = BslQuickFixUtil.createVariable(declarationKeyWord, variableName,
                    indent.get() + interactiveModel.getIndentProvider().getIndent(), lineSeparator);

                //write var to module
                BslQuickFixUtil.writeToDoc(document, offset, variable);

                //linked mode model
                int posDec = offset + declarationKeyWord.length() + 1;
                int posUse = model.getIssue().getOffset() + variable.length();
                int length = variableName.length();

                createLinkedModeModel(interactiveModel, posDec, posUse, length);
            }
        }
        return null;
    }

    //CHECKSTYLE.OFF: LineLength
    private static String getDeclarationKeyword(IXtextBslModuleFixModel model)
    {
        boolean isRussion = model.getScriptVariant() == ScriptVariant.RUSSIAN;
        return !isRussion ? model.getBslGrammar().getDeclareStatementAccess().getVarKeyword_0_0().getValue() : model
            .getBslGrammar()
            .getDeclareStatementAccess()
            .getCyrillicCapitalLetterPeCyrillicSmallLetterIeCyrillicSmallLetterErCyrillicSmallLetterIeCyrillicSmallLetterEmKeyword_0_1()
            .getValue();
    }
    //CHECKSTYLE.ON: LineLength

    private static void createLinkedModeModel(IXtextInteractiveBslModuleFixModel model, int posDec, int posUse,
        int length)
    {
        IXtextDocument document = (IXtextDocument)model.getDocument();
        try
        {
            //create groups - this step is independent of the linked mode
            LinkedPositionGroup group = new LinkedPositionGroup();
            group.addPosition(new LinkedPosition(document, posDec, length));
            group.addPosition(new LinkedPosition(document, posUse, length));
            //set up linked mode
            LinkedModeModel linkedModeModel = model.getLinkedModeModel();
            linkedModeModel.addGroup(group);
            LinkedModeModel.closeAllModels(document);
            linkedModeModel.forceInstall();

            model.enterUiMode();
            model.selectAndRevealForLinkedModeModel(posUse, length);
        }
        catch (Exception e)
        {
            //mark using varible
            model.selectAndRevealForLinkedModeModel(posUse, length);
        }
    }
}
