import {
  RouteAsset,
  RefObj,
  BaseAsset,
  RoutingSpec,
} from "../../../model/assets-model.js";
import { KindEnums } from "@apic/api-model/common/StudioEnums.js";
import { AssetCacheModel } from "../../../model/asset-cache-model.js";
import {
  checkForNullOrUndefined,
  isNullOrUndefined,
} from "../../common/data-helper.js";
import { showWarning } from "./../../common/message-helper.js";

const addAssetRefValuesForRouteKind = (
  refObjects: RefObj[],
  kind: KindEnums,
  result: AssetCacheModel[]
) => {
  if (!isNullOrUndefined(refObjects)) {
    refObjects.forEach((endpoint) => {
      if (!isNullOrUndefined(endpoint.$ref)) {
        result.push({
          kind,
          ref: endpoint.$ref,
          isNewlyAdded: true,
        });
      }
    });
  }
};

const getRefsFromRouteAsset = (asset: BaseAsset): AssetCacheModel[] => {
  const routeAsset = asset as unknown as RouteAsset;
  const spec: RoutingSpec = routeAsset.spec;
  const result: AssetCacheModel[] = [];
  try {
    checkForNullOrUndefined(routeAsset, "Asset is null or undefined");

    // Default endpoint check
    if (spec["default-endpoint"]) {
      const defaultEndpoint = spec["default-endpoint"];
      if (defaultEndpoint.$ref) {
        addAssetRefValuesForRouteKind(
          [{ $ref: defaultEndpoint.$ref }],
          KindEnums.HTTPEndpoint,
          result
        );
      }
    }

    // Loadbalance endpoints check
    if (Array.isArray(spec["loadbalance-endpoints"])) {
      const loadbalanceEndpoints: RefObj[] = spec["loadbalance-endpoints"].map(
        (endpoint) => ({
          $ref: endpoint.$ref || "",
        })
      );
      addAssetRefValuesForRouteKind(loadbalanceEndpoints, KindEnums.HTTPEndpoint, result);
    }

    // Conditional endpoints check
    if (Array.isArray(spec["conditional-endpoints"])) {
      spec["conditional-endpoints"].forEach((conditional) => {
        if (
          typeof conditional.endpoint === "object" &&
          conditional.endpoint.$ref
        ) {
          addAssetRefValuesForRouteKind(
            [{ $ref: conditional.endpoint.$ref }],
            KindEnums.HTTPEndpoint,
            result
          );
        }
      });
    }

    // Mock endpoint check
    if (spec["mock-endpoint"]) {
      const mockEndpoint = spec["mock-endpoint"];
      if (mockEndpoint.$ref) {
        addAssetRefValuesForRouteKind(
          [{ $ref: mockEndpoint.$ref }],
          KindEnums.MockEndpoint,
          result
        );
      }
    }
    return result;
  } catch (error: unknown) {
    showWarning((error as Error).message);
    return [];
  }
};

export { getRefsFromRouteAsset };
