/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * 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.
 */
package com.android.ide.eclipse.adt.internal.lint;

import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.tools.lint.checks.TypoDetector;
import com.android.tools.lint.detector.api.TextFormat;

import org.eclipse.core.resources.IMarker;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.FindReplaceDocumentAdapter;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.w3c.dom.Node;

import java.util.ArrayList;
import java.util.List;

/** Quickfix for fixing typos */
@SuppressWarnings("restriction") // DOM model
final class TypoFix extends DocumentFix {
    private String mTypo;
    private String mReplacement;

    private TypoFix(String id, IMarker marker) {
        super(id, marker);
    }

    @Override
    public String getDisplayString() {
        return String.format("Replace \"%1$s\" by \"%2$s\"", mTypo, mReplacement);
    }

    @Override
    public boolean needsFocus() {
        return false;
    }

    @Override
    public boolean isCancelable() {
        return false;
    }

    @Override
    protected void apply(IDocument document, IStructuredModel model, Node node,
            int start, int end) {
        String message = mMarker.getAttribute(IMarker.MESSAGE, "");
        String typo = TypoDetector.getTypo(message, TextFormat.TEXT);
        if (typo == null) {
            return;
        }
        List<String> replacements = TypoDetector.getSuggestions(message, TextFormat.TEXT);
        if (replacements == null || replacements.isEmpty()) {
            return;
        }

        try {
            String current = document.get(start, end-start);
            if (current.equals(typo)) {
                document.replace(start, end - start, replacements.get(0));
            } else {
                // The buffer has been edited; try to find the typo.
                FindReplaceDocumentAdapter finder = new FindReplaceDocumentAdapter(document);
                IRegion forward = finder.find(start, typo, true /*forward*/, true, true, false);
                IRegion backward = finder.find(start, typo, false /*forward*/, true, true, false);
                if (forward != null && backward != null) {
                    // Pick the closest one
                    int forwardDelta = forward.getOffset() - start;
                    int backwardDelta = start - backward.getOffset();
                    if (forwardDelta < backwardDelta) {
                        start = forward.getOffset();
                    } else {
                        start = backward.getOffset();
                    }
                } else if (forward != null) {
                    start = forward.getOffset();
                } else if (backward != null) {
                    start = backward.getOffset();
                } else {
                    return;
                }
                end = start + typo.length();
                document.replace(start, end - start, replacements.get(0));
            }
        } catch (BadLocationException e) {
            AdtPlugin.log(e, null);
        }
    }

    @Override
    protected List<LintFix> getAllFixes() {
        String message = mMarker.getAttribute(IMarker.MESSAGE, "");
        String typo = TypoDetector.getTypo(message, TextFormat.TEXT);
        List<String> replacements = TypoDetector.getSuggestions(message, TextFormat.TEXT);
        if (replacements != null && !replacements.isEmpty() && typo != null) {
            List<LintFix> allFixes = new ArrayList<LintFix>(replacements.size());
            for (String replacement : replacements) {
                TypoFix fix = new TypoFix(mId, mMarker);
                fix.mTypo = typo;
                fix.mReplacement = replacement;
                allFixes.add(fix);
            }

            return allFixes;
        }

        return null;
    }
}