/*
 * Copyright (C) 2011 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.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.SwtUtils;
import com.android.tools.lint.detector.api.Issue;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;

import java.io.File;
import java.util.Comparator;

/** A column shown in the {@link LintList} */
abstract class LintColumn implements Comparator<IMarker> {
    protected final LintList mList;

    protected LintColumn(@NonNull LintList list) {
        mList = list;
    }

    /** @return true if this column should be shown by default */
    public boolean isVisibleByDefault() {
        return true;
    }

    /** @return true if this column's text should be left aligned */
    public boolean isLeftAligned() {
        return true;
    }

    /**
     * @return the number of pixels that this column should show by default
     */
    public int getPreferredWidth() {
        return getPreferredCharWidth() * SwtUtils.getAverageCharWidth(mList.getDisplay(),
                mList.getTree().getFont());
    }

    /**
     * @return the number of characters that this column should show by default
     */
    public int getPreferredCharWidth() {
        return 15;
    }

    /**
     * @return the title of the column
     */
    @NonNull
    public abstract String getColumnHeaderText();

    /**
     * @return the image of the column, or null
     */
    public Image getColumnHeaderImage() {
        return null;
    }

    /**
     * @param marker the {@link IMarker} to get the value for
     * @return the value of this column for the given marker
     */
    public abstract String getValue(@NonNull IMarker marker);

    /**
     * @param marker the {@link IMarker} to get the value for
     * @return the styled value of this column for the given marker
     */
    public StyledString getStyledValue(@NonNull IMarker marker) {
        return null;
    }

    /**
     * @param marker the {@link IMarker} to get the image for
     * @return The image for this particular column, or null
     */
    @Nullable
    public Image getImage(@NonNull IMarker marker) {
        return null;
    }

    /**
     * @param marker the {@link IMarker} to get the font for
     * @return The font for this particular column, or null
     */
    @Nullable
    public Font getFont(@NonNull IMarker marker) {
        return null;
    }

    /**
     * @return true if the sort should be in ascending order. If false, sort in descending order.
     */
    public boolean isAscending() {
        return true;
    }

    /**
     * @return true if this column should be visible by default
     */
    public boolean visibleByDefault() {
        return true;
    }

    @Override
    public int compare(IMarker o1, IMarker o2) {
        return getValue(o1).compareTo(getValue(o2));
    }

    // Used for default LabelProvider
    @Override
    public String toString() {
        return getColumnHeaderText();
    }

    static class MessageColumn extends LintColumn {

        public MessageColumn(LintList list) {
            super(list);
        }

        @Override
        public @NonNull String getColumnHeaderText() {
            return "Description";
        }

        @Override
        public int getPreferredCharWidth() {
            return 80;
        }

        @Override
        public String getValue(@NonNull IMarker marker) {
            return getStyledValue(marker).toString();
        }

        @Override
        public StyledString getStyledValue(@NonNull IMarker marker) {
            StyledString styledString = new StyledString();

            String message = marker.getAttribute(IMarker.MESSAGE, "");
            styledString.append(message);

            int count = mList.getCount(marker);
            if (count > 1) {
                styledString.append(String.format(" (%2$d items)", message, count),
                        StyledString.COUNTER_STYLER);
            }

            return styledString;
        }

        @Override
        public Image getImage(@NonNull IMarker marker) {
            int severity = marker.getAttribute(IMarker.SEVERITY, 0);
            ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages();
            switch (severity) {
                case IMarker.SEVERITY_ERROR:
                    if (LintFix.hasFix(EclipseLintClient.getId(marker))) {
                        return IconFactory.getInstance().getIcon("quickfix_error");   //$NON-NLS-1$
                    }
                    return sharedImages.getImage(ISharedImages.IMG_OBJS_ERROR_TSK);
                case IMarker.SEVERITY_WARNING:
                    if (LintFix.hasFix(EclipseLintClient.getId(marker))) {
                        return IconFactory.getInstance().getIcon("quickfix_warning"); //$NON-NLS-1$
                    }
                    return sharedImages.getImage(ISharedImages.IMG_OBJS_WARN_TSK);
                case IMarker.SEVERITY_INFO:
                    return sharedImages.getImage(ISharedImages.IMG_OBJS_INFO_TSK);
                default:
                    return null;
            }
        }

        @Override
        public Font getFont(@NonNull IMarker marker) {
            int severity = marker.getAttribute(IMarker.SEVERITY, 0);
            if (severity == IMarker.SEVERITY_ERROR) {
                return JFaceResources.getFontRegistry().getBold(
                        JFaceResources.DEFAULT_FONT);
            }

            return null;
        }

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

        @Override
        public int compare(IMarker marker2, IMarker marker1) {
            // Reversing order marker1/marker2 here since we want to use a "descending" column
            // sorting marker to indicate priority. (Note that we return from isAscending too.)

            String id1 = EclipseLintClient.getId(marker1);
            String id2 = EclipseLintClient.getId(marker2);
            if (id1 == null || id2 == null) {
                return marker1.getResource().getName().compareTo(
                        marker2.getResource().getName());
            }
            Issue issue1 = mList.getIssue(id1);
            Issue issue2 = mList.getIssue(id2);
            if (issue1 == null || issue2 == null) {
                // Unknown issue? Can happen if you have used a third party detector
                // which is no longer available but which left a persistent marker behind
                return id1.compareTo(id2);
            }
            int delta = mList.getSeverity(issue1).ordinal() -
                    mList.getSeverity(issue2).ordinal();
            if (delta != 0) {
                return delta;
            }
            delta = issue2.getPriority() - issue1.getPriority();
            if (delta != 0) {
                return delta;
            }
            delta = issue1.getCategory().compareTo(issue2.getCategory());
            if (delta != 0) {
                return delta;
            }
            delta = id1.compareTo(id2);
            if (delta != 0) {
                return delta;
            }

            IResource resource1 = marker1.getResource();
            IResource resource2 = marker2.getResource();

            IProject project1 = resource1.getProject();
            IProject project2 = resource2.getProject();
            delta = project1.getName().compareTo(project2.getName());
            if (delta != 0) {
                return delta;
            }

            delta = resource1.getName().compareTo(resource2.getName());
            if (delta != 0) {
                return delta;
            }

            return marker1.getAttribute(IMarker.LINE_NUMBER, 0)
                    - marker2.getAttribute(IMarker.LINE_NUMBER, 0);
        }
    }

    static class CategoryColumn extends LintColumn {

        public CategoryColumn(LintList list) {
            super(list);
        }

        @Override
        public @NonNull String getColumnHeaderText() {
            return "Category";
        }

        @Override
        public int getPreferredCharWidth() {
            return 20;
        }

        @Override
        public String getValue(@NonNull IMarker marker) {
            Issue issue = mList.getIssue(marker);
            if (issue != null) {
                return issue.getCategory().getFullName();
            } else {
                return "";
            }
        }
    }

    static class LocationColumn extends LintColumn {
        public LocationColumn(LintList list) {
            super(list);
        }

        @Override
        public @NonNull String getColumnHeaderText() {
            return "Location";
        }

        @Override
        public int getPreferredCharWidth() {
            return 35;
        }

        @Override
        public String getValue(@NonNull IMarker marker) {
            return getStyledValue(marker).toString();
        }

        @Override
        public StyledString getStyledValue(@NonNull IMarker marker) {
            StyledString styledString = new StyledString();

            // Combined location
            IResource resource = marker.getResource();
            if (resource instanceof IProject) {
                styledString.append(resource.getName());
            } else {
                // Show location as Parent/File:Line in Project
                styledString.append(resource.getName());
                if (resource instanceof IFile) {
                    int line = marker.getAttribute(IMarker.LINE_NUMBER, -1);
                    if (line > 1) {
                        styledString.append(':').append(Integer.toString(line));
                    }
                } else if (resource instanceof IFolder) {
                    styledString.append(File.separatorChar);
                }

                if (!(resource.getParent() instanceof IProject)) {
                    styledString.append(" in ");
                    styledString.append(resource.getParent().getName(),
                            StyledString.DECORATIONS_STYLER);
                }

                styledString.append(String.format(" (%1$s)", resource.getProject().getName()),
                        StyledString.QUALIFIER_STYLER);
            }

            return styledString;
        }

        @Override
        public int compare(IMarker marker1, IMarker marker2) {
            IResource resource1 = marker1.getResource();
            IResource resource2 = marker2.getResource();

            IProject project1 = resource1.getProject();
            IProject project2 = resource2.getProject();
            int delta = project1.getName().compareTo(project2.getName());
            if (delta != 0) {
                return delta;
            }

            delta = resource1.getName().compareTo(resource2.getName());
            if (delta != 0) {
                return delta;
            }

            return marker1.getAttribute(IMarker.LINE_NUMBER, 0)
                    - marker2.getAttribute(IMarker.LINE_NUMBER, 0);
        }
    }

    static class FileColumn extends LintColumn {
        public FileColumn(LintList list) {
            super(list);
        }

        @Override
        public @NonNull String getColumnHeaderText() {
            return "File";
        }

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

        @Override
        public int getPreferredCharWidth() {
            return 12;
        }

        @Override
        public String getValue(@NonNull IMarker marker) {
            if (marker.getResource() instanceof IFile) {
                return marker.getResource().getName();
            } else {
                return "";
            }
        }
    }

    static class PathColumn extends LintColumn {
        public PathColumn(LintList list) {
            super(list);
        }

        @Override
        public @NonNull String getColumnHeaderText() {
            return "Path";
        }

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

        @Override
        public int getPreferredCharWidth() {
            return 25;
        }

        @Override
        public String getValue(@NonNull IMarker marker) {
            return marker.getResource().getFullPath().toOSString();
        }
    }

    static class LineColumn extends LintColumn {
        public LineColumn(LintList list) {
            super(list);
        }

        @Override
        public @NonNull String getColumnHeaderText() {
            return "Line";
        }

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

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

        @Override
        public int getPreferredCharWidth() {
            return 4;
        }

        @Override
        public String getValue(@NonNull IMarker marker) {
            int line = getLine(marker);
            if (line >= 1) {
                return Integer.toString(line);
            } else {
                return "";
            }
        }

        private int getLine(IMarker marker) {
            if (marker.getResource() instanceof IFile) {
                int line = marker.getAttribute(IMarker.LINE_NUMBER, -1);
                return line;
            }

            return -1;
        }
        @Override
        public int compare(IMarker marker1, IMarker marker2) {
            return getLine(marker1) - getLine(marker2);
        }
    }

    static class PriorityColumn extends LintColumn {
        public PriorityColumn(LintList list) {
            super(list);
        }

        @Override
        public @NonNull String getColumnHeaderText() {
            return "Priority";
        }

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

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

        @Override
        public int getPreferredCharWidth() {
            return 2;
        }

        @Override
        public String getValue(@NonNull IMarker marker) {
            int priority = getPriority(marker);
            if (priority > 0) {
                return Integer.toString(priority);
            }
            return "";
        }

        private int getPriority(IMarker marker) {
            Issue issue = mList.getIssue(marker);
            if (issue != null) {
                return issue.getPriority();
            }
            return 0;
        }

        @Override
        public int compare(IMarker marker1, IMarker marker2) {
            return getPriority(marker1) - getPriority(marker2);
        }

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