import { EntityManager } from 'typeorm/entity-manager/EntityManager';
import { AssetEntity } from '../entities/asset.entity';
import { ApiError } from '../common/error/api-error';
import { ApiErrorCodes } from '../common/error/api-error-codes';

export async function getAllParentIdsOfAssetIdsTx(
  tx: EntityManager,
  asset_ids: string[],
): Promise<string[]> {
  if (asset_ids.length === 0) {
    return [];
  }
  return (
    await tx.getRepository(AssetEntity).query(
      `WITH RECURSIVE r AS (
          SELECT unnest(parent_ids) parent_id, a.id
          FROM assets a
          UNION
          SELECT unnest(a.parent_ids) parent_id, r.id
          FROM r
          JOIN assets a ON a.id = r.parent_id
      )
      SELECT DISTINCT r.parent_id as id
      FROM r
      WHERE r.id = ANY($1)
    `,
      [asset_ids],
    )
  ).map((p) => p.id) as string[];
}

export async function checkAssetNotParentOfItselfOrThrowTx(
  tx: EntityManager,
  asset_id: string,
  parent_ids: string[],
): Promise<string[]> {
  if (parent_ids.length === 0) {
    return [];
  }
  if (parent_ids.includes(asset_id)) {
    throw new ApiError(
      'Asset cannot be parent of itself',
      ApiErrorCodes.ACTION_NOT_AVAILABLE,
    );
  }
  const nested_parents = await getAllParentIdsOfAssetIdsTx(tx, parent_ids);
  if (nested_parents.includes(asset_id)) {
    throw new ApiError(
      'Asset cannot be parent of itself',
      ApiErrorCodes.ACTION_NOT_AVAILABLE,
    );
  }
  return [...new Set([...parent_ids, ...nested_parents])];
}
