/*-
 * ~~~~~~licensing~~~~~~
 * application-shell
 * ==========
 * 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.integration.applications.shell.project;

import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.lifecycle.Reference;
import org.apache.karaf.shell.api.action.lifecycle.Service;
import org.apache.karaf.shell.support.ansi.SimpleAnsi;

import ru.entaxy.esb.resources.EntaxyResource;
import ru.entaxy.esb.resources.EntaxyResourceService;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.base.support.karaf.shell.ShellTableFixed;
import ru.entaxy.platform.integration.applications.EntaxyApplicationProject;
import ru.entaxy.platform.integration.applications.EntaxyApplicationProjectVersion;
import ru.entaxy.platform.integration.applications.descriptor.ApplicationComponent;
import ru.entaxy.platform.integration.applications.descriptor.ApplicationContentItem;
import ru.entaxy.platform.integration.applications.descriptor.ApplicationDescriptor;
import ru.entaxy.platform.integration.applications.descriptor.ApplicationRequirement;
import ru.entaxy.platform.integration.applications.shell.ApplicationShell;
import ru.entaxy.platform.objects.runtime.EntaxyRuntimeObject;
import ru.entaxy.platform.objects.runtime.EntaxyRuntimeObjectService;

@Service
@Command(name = "project-version-build-info", scope = ApplicationShell.COMMAND_SCOPE)
public class VersionBuildInfoCommand extends ManagedVersionCommand {

    @Reference
    EntaxyRuntimeObjectService entaxyRuntimeObjectService;

    @Reference
    EntaxyResourceService entaxyResourceService;

    @Override
    protected void doExecute(EntaxyApplicationProject application, EntaxyApplicationProjectVersion version) {

        if (!version.isBuildAvailable()) {
            // print output
            System.out.println("Build is not available");
            return;
        }

        ApplicationDescriptor applicationDescriptor = version.getBuildInfo();

        // output main data
        String mainData = "\n"
                .concat("Application  : ").concat(applicationDescriptor.name).concat("\n")
                .concat("Group        : ").concat(applicationDescriptor.group).concat("\n")
                .concat("Version      : ").concat(applicationDescriptor.version).concat("\n")
                .concat("Build by     : ").concat(CommonUtils.getValid(applicationDescriptor.buildBy, "")).concat("\n")
                .concat("Built on     : ").concat(applicationDescriptor.buildOn).concat("\n")
                .concat("Maven        : ").concat(applicationDescriptor.mavenUrl).concat("\n")
                .concat("Asset        : ").concat(applicationDescriptor.mavenAsset).concat("\n");
        System.out.println(mainData);

        // output features location info
        System.out.println(SimpleAnsi.RESET + SimpleAnsi.INTENSITY_NORMAL + "\n\t--- FEATURE REPO:");
        if (applicationDescriptor.features == null) {
            System.out.println(":: NOT FOUND");
        } else {
            String featuresData =
                    ("  INTERNAL : ").concat(applicationDescriptor.features.internalLocation).concat("\n")
                            .concat("  ").concat("MAVEN    : ").concat(applicationDescriptor.features.mavenLocation)
                            .concat("\n")
                            .concat("  ").concat("TARGET   : ")
                            .concat(applicationDescriptor.features.getFullTargetLocation());
            System.out.println(featuresData);

        }

        // output items
        System.out.println("\n\t--- ITEMS:");
        ShellTableFixed itemsTable = new ShellTableFixed();
        itemsTable.column("Id");
        itemsTable.column("Type");
        itemsTable.column("Component");

        for (ApplicationContentItem item : applicationDescriptor.items) {
            itemsTable.addRow().addContent(item.id, item.type.name(), item.componentId);
        }

        itemsTable.print(System.out);

        // output requirements
        System.out.println("\n\t--- REQUIREMENTS:");
        ShellTableFixed requirementsTable = new ShellTableFixed();
        requirementsTable.column("Id").colorProvider(ApplicationShell.normalColorProvider);
        requirementsTable.column("Type").colorProvider(ApplicationShell.normalColorProvider);
        requirementsTable.column("Scope").colorProvider(ApplicationShell.normalColorProvider);
        requirementsTable.column("Status").colorProvider(ApplicationShell.requirementStatusColorProvider).alignCenter();

        for (ApplicationRequirement req : applicationDescriptor.requirements) {
            requirementsTable.addRow().addContent(
                    req.id,
                    req.type.name(),
                    req.scope.name(),
                    checkRequirement(req) ? "V" : "X");
        }

        requirementsTable.print(System.out);

        // output components
        System.out.println(SimpleAnsi.RESET + SimpleAnsi.INTENSITY_NORMAL + "\n\t--- COMPONENTS:");
/*        ShellTableFixed componentsTable = new ShellTableFixed();
componentsTable.column("Id");
componentsTable.column("Type");
componentsTable.column("Priority");
componentsTable.column("Internal location");
componentsTable.column("Maven location");
*/
        for (ApplicationComponent component : applicationDescriptor.components) {
/*            componentsTable.addRow().addContent(
        component.id,
        component.type.name(),
        component.priority,
        component.internalLocation,
        component.mavenLocation);
*/
            String componentData = component.id.concat("\n")
                    .concat("\t").concat("TYPE     : ").concat(component.type.name()).concat("\n")
                    .concat("\t").concat("PRIORITY : ").concat(component.priority + "").concat("\n")
                    .concat("\t").concat("INTERNAL : ").concat(component.internalLocation).concat("\n")
                    .concat("\t").concat("MAVEN    : ").concat(component.mavenLocation).concat("\n")
                    .concat("\t").concat("TARGET   : ").concat(component.getFullTargetLocation());
            System.out.println(componentData);
        }
        // componentsTable.print(System.out);

    }

    protected boolean checkRequirement(ApplicationRequirement requirement) {
        switch (requirement.type) {
            case OBJECT:
                EntaxyRuntimeObject runtimeObject = entaxyRuntimeObjectService.getRuntimeObject(requirement.id);
                return runtimeObject != null && !runtimeObject.isGhost();
            case RESOURCE:
                EntaxyResource entaxyResource = entaxyResourceService.getResource(requirement.id);
                return entaxyResource.exists();
            case BUNDLE:
            case CONFIG:
                // TODO implement
                return true;
            default:
                return true;
        }
    }

}
