import type {
  CompilationJobCreationError,
  FailedFileBuildResult,
  FileBuildResult,
  SolidityBuildSystem,
} from "../../../types/solidity.js";

import { HardhatError } from "@nomicfoundation/hardhat-errors";

import { FileBuildResultType } from "../../../types/solidity.js";

type SolidityBuildResults =
  | Map<string, FileBuildResult>
  | CompilationJobCreationError;
type SuccessfulSolidityBuildResults = Map<
  string,
  Exclude<FileBuildResult, FailedFileBuildResult>
>;

/**
 * This function asserts that the given Solidity build results are successful.
 * It throws a HardhatError if the build results indicate that the compilation
 * job failed.
 */
export function throwIfSolidityBuildFailed(
  solidity: SolidityBuildSystem,
  results: SolidityBuildResults,
): asserts results is SuccessfulSolidityBuildResults {
  if (!solidity.isSuccessfulBuildResult(results)) {
    throw new HardhatError(
      HardhatError.ERRORS.CORE.SOLIDITY.COMPILATION_JOB_CREATION_ERROR,
      {
        reason: results.formattedReason,
        rootFilePath: results.rootFilePath,
        buildProfile: results.buildProfile,
      },
    );
  }

  const successful = [...results.values()].every(
    ({ type }) =>
      type === FileBuildResultType.CACHE_HIT ||
      type === FileBuildResultType.BUILD_SUCCESS,
  );

  if (!successful) {
    throw new HardhatError(HardhatError.ERRORS.CORE.SOLIDITY.BUILD_FAILED);
  }
}
