/*-
 * ~~~~~~licensing~~~~~~
 * platform-manager-core
 * ==========
 * Copyright (C) 2020 - 2025 EmDev LLC
 * ==========
 * You may not use this file except in accordance with the License Terms of the Copyright
 * Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
 * rights to the Software and any copies are the property of the Copyright Holder. Unless
 * it is explicitly allowed the Copyright Holder, the User is prohibited from using the
 * Software for commercial purposes to provide services to third parties.
 * 
 * The Copyright Holder hereby declares that the Software is provided on an "AS IS".
 * Under no circumstances does the Copyright Holder guarantee or promise that the
 * Software provided by him will be suitable or not suitable for the specific purposes
 * of the User, that the Software will meet all commercial and personal subjective
 * expectations of the User, that the Software will work properly, without technical
 * errors, quickly and uninterruptedly.
 * 
 * Under no circumstances shall the Copyright Holder or its Affiliates is not liable
 * to the User for any direct or indirect losses of the User, his expenses or actual
 * damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
 * or damage to data, property, etc.
 * ~~~~~~/licensing~~~~~~
 */
package ru.entaxy.platform.manager.shell;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.apache.felix.hc.api.Result;
import org.apache.felix.hc.api.Result.Status;
import org.apache.felix.hc.api.execution.HealthCheckExecutionResult;
import org.apache.karaf.shell.support.ansi.SimpleAnsi;
import org.apache.karaf.shell.support.table.ShellTable;

public class Utils {
	
	//Welocme color
	public static String WLC = "\u001B[36m";
    //OK color:  High Intensity Foreground Color: Green
	public static String OKC = SimpleAnsi.COLOR_GREEN;
    //WARN color:  High Intensity Foreground Color: Yellow
	public static String WARNC = SimpleAnsi.COLOR_YELLOW;
    //CRITICAL color:  High Intensity Foreground Color: Red
	public static String CRT = SimpleAnsi.COLOR_RED + SimpleAnsi.INTENSITY_BOLD;
    //reset colors
	public static String NOR = "\33[0m";
	
	public static Function<String, String> resultStatusColorProvider = (
    		str ->{
    			try {
    				Result.Status status = Result.Status.valueOf(str);
    				switch (status) {
    				case CRITICAL:
    				case HEALTH_CHECK_ERROR:
    					return CRT + SimpleAnsi.INTENSITY_BOLD;
    				case WARN:
    				case TEMPORARILY_UNAVAILABLE:
    					return WARNC + SimpleAnsi.INTENSITY_BOLD;
    				default:
    					return OKC + SimpleAnsi.INTENSITY_BOLD;
    				}
    			} catch (Exception e) {
    				
    			}
    			return "";
    		}
    	);

	public static Function<String, String> normalColorProvider = (str -> SimpleAnsi.RESET + SimpleAnsi.INTENSITY_NORMAL);
	
	
    public static String colored(Result.Status status) {
    	String color = status.equals(Result.Status.CRITICAL)
    			? CRT + SimpleAnsi.INTENSITY_BOLD
    			: status.equals(Result.Status.WARN)
    				? WARNC + SimpleAnsi.INTENSITY_BOLD
    				: OKC + SimpleAnsi.INTENSITY_BOLD;
    	return color + status.name() + NOR + SimpleAnsi.INTENSITY_NORMAL;
    }
	
	
	public static ShellTable createTable(Collection<HealthCheckExecutionResult> results) {
		
    	ShellTableFixed table = new ShellTableFixed();
    	table.column("Status").colorProvider(resultStatusColorProvider);
    	table.column("Name").colorProvider(normalColorProvider);
    	table.column("Title").colorProvider(normalColorProvider);
    	table.column("Log").colorProvider(normalColorProvider).wrap(true).maxSize(100);
    	
    	for (HealthCheckExecutionResult exResult: results) {
    		
    		Result result = exResult.getHealthCheckResult();
    		
    		String hcName = exResult.getHealthCheckMetadata().getName();
    		String hcTitle = exResult.getHealthCheckMetadata().getTitle();
    		List<String> hcTags = exResult.getHealthCheckMetadata().getTags();
    		
    		final List<String> logData = new ArrayList<>();
    		result.forEach(entry -> {if (!entry.getStatus().equals(Status.OK)) logData.add(entry.getMessage());});
    		
    		String messages = logData.stream().collect(Collectors.joining("\n"));
    		
    		table.addRow().addContent(
    				result.getStatus().name()
    				, hcName
    				, hcTitle
    				, messages
    				);
    		
    	}
    	
		return table;
	}

	public static Result.Status getOverallStatus(Collection<HealthCheckExecutionResult> results){
		
		Result.Status overallStatus = Result.Status.OK;
    	
		for (HealthCheckExecutionResult exResult: results) {
    		
    		Result result = exResult.getHealthCheckResult();
    		
    		if (isMoreSerious(overallStatus, result.getStatus()))
    			overallStatus = mapStatus(result.getStatus());
    	}
    	
		return overallStatus;
	}
	
    public static boolean isMoreSerious(Result.Status currentStatus, Result.Status newStatus) {
    	if (currentStatus.equals(newStatus))
    		return false;
    	if (currentStatus.equals(Result.Status.OK))
    		return true;
    	Result.Status st = mapStatus(newStatus);
    	if (st.equals(Result.Status.CRITICAL))
    		return true;
    	return false;
    }
    
    public static Result.Status mapStatus(Result.Status origin){
    	switch (origin) {
		case OK:
			return Result.Status.OK;
		case CRITICAL:
		case HEALTH_CHECK_ERROR:
			return Result.Status.CRITICAL;
		case TEMPORARILY_UNAVAILABLE:
		case WARN:
			return Status.WARN;
		default:
			return Result.Status.OK;
		}
    }
	
	
}
