/*=============================================================================#
 # Copyright (c) 2000, 2021 Stephan Wahlbrink 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, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.jcommons.status.eplatform;

import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.ARRAY_CONTENTS;
import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.FIELD;
import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.PARAMETER;
import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.RETURN_TYPE;
import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.TYPE_ARGUMENT;
import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.TYPE_BOUND;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IProgressMonitorWithBlocking;
import org.eclipse.core.runtime.IStatus;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.BasicProgressMonitor;
import org.eclipse.statet.jcommons.status.BasicProgressMonitor.ProgressData;
import org.eclipse.statet.jcommons.status.InfoStatus;
import org.eclipse.statet.jcommons.status.MultiStatus;
import org.eclipse.statet.jcommons.status.NullProgressMonitor;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.Status;
import org.eclipse.statet.jcommons.status.StatusException;


/**
 * A utility class to work with IStatus.
 */
@NonNullByDefault({ PARAMETER, RETURN_TYPE, FIELD, TYPE_BOUND, TYPE_ARGUMENT, ARRAY_CONTENTS })
public class EStatusUtils {
	
	
	private final static IStatus[] NO_ECHILDREN= new IStatus[0];
	
	private static class EStatus implements IStatus {
		
		
		private final Status status;
		
		
		public EStatus(final Status status) {
			this.status= status;
		}
		
		
		@Override
		public int getSeverity() {
			return this.status.getSeverity() & 0xFF;
		}
		
		@Override
		public boolean isOK() {
			return (this.status.getSeverity() == Status.OK);
		}
		
		@Override
		public boolean matches(final int severityMask) {
			return ((this.status.getSeverity() & severityMask) != 0);
		}
		
		@Override
		public String getPlugin() {
			return this.status.getBundleId();
		}
		
		@Override
		public int getCode() {
			return this.status.getCode();
		}
		
		@Override
		public String getMessage() {
			return this.status.getMessage();
		}
		
		@Override
		public @Nullable Throwable getException() {
			return this.status.getException();
		}
		
		
		@Override
		public boolean isMultiStatus() {
			return false;
		}
		
		@Override
		public IStatus[] getChildren() {
			return NO_ECHILDREN;
		}
		
		
		@Override
		public String toString() {
			return this.status.toString();
		}
		
	}
	
	private static class EMultiStatus extends EStatus {
		
		
		private final IStatus [] children;
		
		
		public EMultiStatus(final Status status, final IStatus[] children) {
			super(status);
			this.children= children;
		}
		
		
		@Override
		public boolean isMultiStatus() {
			return true;
		}
		
		@Override
		public IStatus [] getChildren() {
			return this.children;
		}
		
	}
	
	
	public static IStatus convert(final Status status) {
		if (status.isMultiStatus()) {
			final var children= status.getChildren();
			final var convertedChildren= new @NonNull IStatus[children.size()];
			for (int i= 0; i < convertedChildren.length; i++) {
				convertedChildren[i]= convert(children.get(i));
			}
			return new EMultiStatus(status, convertedChildren);
		}
		else {
			if (status == Status.OK_STATUS) {
				return org.eclipse.core.runtime.Status.OK_STATUS;
			}
			if (status == Status.CANCEL_STATUS) {
				return org.eclipse.core.runtime.Status.CANCEL_STATUS;
			}
			return new EStatus(status);
		}
	}
	
	public static Status convert(final IStatus status) {
		if (status.isMultiStatus()) {
			final var children= status.getChildren();
			final var convertedChildren= new @NonNull Status[children.length];
			for (int i= 0; i < convertedChildren.length; i++) {
				convertedChildren[i]= convert(children[i]);
			}
			return new MultiStatus(status.getPlugin(), status.getCode(),
					status.getMessage(), status.getException(),
					ImCollections.newList(convertedChildren) );
		}
		else {
			if (status == org.eclipse.core.runtime.Status.OK_STATUS) {
				return Status.OK_STATUS;
			}
			if (status == org.eclipse.core.runtime.Status.CANCEL_STATUS) {
				return Status.CANCEL_STATUS;
			}
			if (status instanceof EStatus) {
				return ((EStatus) status).status;
			}
			return Status.newStatus(status.getSeverity(),
					status.getPlugin(), status.getCode(),
					status.getMessage(), status.getException() );
		}
	}
	
	public static CoreException convert(final StatusException e) {
		final CoreException convertedException= new CoreException(convert(e.getStatus()));
		e.setStackTrace(e.getStackTrace());
		return convertedException;
	}
	
	public static StatusException convert(final CoreException e) {
		final StatusException convertedException= new StatusException(convert(e.getStatus()));
		convertedException.setStackTrace(e.getStackTrace());
		return convertedException;
	}
	
	
	private static class EProgressData extends ProgressData {
		
		
		private static final int TOTAL= 1 << 30;
		
		
		private final IProgressMonitor monitor;
		
		private int workRemaining= TOTAL;
		
		
		public EProgressData(final IProgressMonitor monitor) {
			this.monitor= monitor;
		}
		
		
		@Override
		public boolean isCanceled() {
			return this.monitor.isCanceled();
		}
		
		@Override
		protected void setCanceled(final boolean state) {
			this.monitor.setCanceled(state);
		}
		
		@Override
		protected void onDataChanged(final byte data) {
			switch (data) {
			case MAIN_TASK_NAME:
				this.monitor.subTask(""); //$NON-NLS-1$
				this.monitor.setTaskName(getMainTaskName());
				break;
			case SUB_TASK_NAME:
				this.monitor.subTask(getSubTaskName());
				break;
			case PROGRESS_RATE:
				if (this.workRemaining >= 0) {
					final int workRemaining= (int) (getProgress() * TOTAL);
					if (workRemaining < this.workRemaining) {
						this.monitor.worked(this.workRemaining - workRemaining);
					}
					this.workRemaining= workRemaining;
				}
				break;
			case BLOCKED:
				{	final Status blocked= getBlocked();
					if (blocked != null) {
						this.monitor.setBlocked(EStatusUtils.convert(blocked));
					}
					else {
						this.monitor.clearBlocked();
					}
				}
			}
		}
		
	}
	
	public static ProgressMonitor convert(final @Nullable IProgressMonitor eMonitor,
			final String name, final int totalWork, final int flags) {
		if (eMonitor == null) {
			return new NullProgressMonitor().newSubMonitor(flags);
		}
		
		final EProgressData data= new EProgressData(eMonitor);
		final BasicProgressMonitor convertedMonitor= new BasicProgressMonitor(data, flags);
		if (totalWork > 0) {
			eMonitor.beginTask(name, EProgressData.TOTAL);
			convertedMonitor.beginTask(name, totalWork);
		}
		else {
			eMonitor.beginTask(name, IProgressMonitor.UNKNOWN);
			convertedMonitor.beginTask(name, ProgressMonitor.UNKNOWN);
			data.workRemaining= -1;
		}
		return convertedMonitor;
	}
	
	public static ProgressMonitor convert(final @Nullable IProgressMonitor eMonitor,
			final String name, final int totalWork) {
		return convert(eMonitor, name, totalWork, ProgressMonitor.SUPPRESS_NONE);
	}
	
	public static ProgressMonitor convert(final @Nullable IProgressMonitor eMonitor,
			final int totalWork) {
		return convert(eMonitor, "", totalWork, ProgressMonitor.SUPPRESS_NONE); //$NON-NLS-1$
	}
	
	public static ProgressMonitor convert(final @Nullable IProgressMonitor eMonitor) {
		return convert(eMonitor, "", 1, ProgressMonitor.SUPPRESS_NONE); //$NON-NLS-1$
	}
	
	public static ProgressMonitor convertChild(final @Nullable IProgressMonitor eMonitor) {
		return convert(eMonitor, "", 1, ProgressMonitor.SUPPRESS_BEGINTASK_NAME); //$NON-NLS-1$
	}
	
	private static class EProgressMonitor implements IProgressMonitorWithBlocking {
		
		
		private static final Status BLOCKED_NO_DETAIL= new InfoStatus("unknown", //$NON-NLS-1$
				"blocked" );
		
		
		private final ProgressMonitor m;
		
		private int workRemaining;
		
		public EProgressMonitor(final ProgressMonitor m) {
			this.m= m;
		}
		
		
		@Override
		public void beginTask(final String name, final int totalWork) {
			this.workRemaining= totalWork;
			this.m.beginTask(name, totalWork);
		}
		
		@Override
		public void setTaskName(final String name) {
			this.m.beginTask(name, this.workRemaining);
		}
		
		@Override
		public void subTask(final String name) {
			this.m.beginSubTask(name);
		}
		
		@Override
		public boolean isCanceled() {
			return this.m.isCanceled();
		}
		
		@Override
		public void setCanceled(final boolean value) {
			this.m.setCanceled(value);
		}
		
		@Override
		public void worked(int work) {
			if (this.workRemaining > 0 && work > 0) {
				if (work > this.workRemaining) {
					work= this.workRemaining;
				}
				this.workRemaining-= work;
				this.m.addWorked(work);
			}
		}
		
		@Override
		public void done() {
			this.workRemaining= 0;
			this.m.setWorkRemaining(0);
		}
		
		@Override
		public void internalWorked(final double work) {
		}
		
		
		@Override
		public void setBlocked(final @Nullable IStatus reason) {
			this.m.setBlocked((reason != null) ? convert(reason) : BLOCKED_NO_DETAIL);
		}
		
		@Override
		public void clearBlocked() {
			this.m.clearBlocked();
		}
		
	}
	
	public static IProgressMonitor convert(final @Nullable ProgressMonitor m,
			final String name, final int totalWork) {
		if (m == null) {
			return new org.eclipse.core.runtime.NullProgressMonitor();
		}
		final EProgressMonitor convertedMonitor= new EProgressMonitor(m);
		convertedMonitor.beginTask(name, totalWork);
		return convertedMonitor;
	}
	
	public static IProgressMonitor convert(final @Nullable ProgressMonitor m,
			final int totalWork) {
		return convert(m, "", totalWork); //$NON-NLS-1$
	}
	
	public static IProgressMonitor convert(final @Nullable ProgressMonitor m) {
		if (m == null) {
			return new org.eclipse.core.runtime.NullProgressMonitor();
		}
		return new EProgressMonitor(m);
	}
	
}
