import {
  CwebStore,
  isResolvedBlock,
  isResolvedRead,
  isResolvedStore,
  isResolvedTake,
  ResolvedOperation,
  ResolvedRead,
  ResolvedTake,
} from '@coinweb/contract-kit';
import { CwebBlock } from '@coinweb/contract-kit/dist/esm/operations/block';
import { CwebCallRefResolved, isResolvedCall } from '@coinweb/contract-kit/dist/esm/operations/call';
import { ResolvedBlock } from '@coinweb/contract-kit/dist/types/operations/block';
import { GBlock, GCall, GRead, GStore, GTake } from '@coinweb/contract-kit/dist/types/operations/generics';
import { CwebTake } from '@coinweb/contract-kit/dist/types/operations/take';

import {
  PreparedExecOp,
  PreparedExtendedStoreOp,
  PreparedLockOp,
  PreparedOp,
  PreparedUnlockOp,
  ResolvedChildOp,
  ResolvedExecOp,
  ResolvedLockOp,
  ResolvedOp,
  ResolvedSlotOp,
  ResolvedUnlockOp,
} from '../../types';

export const isResolvedSlotOp = (op?: ResolvedOp | null): op is ResolvedSlotOp => {
  return !!(op && 'SlotOp' in op);
};

export const isResolvedExecOp = (op?: ResolvedOp | null): op is ResolvedExecOp => {
  return !!(op && 'ExecOp' in op);
};

export const isResolvedChildOp = (op?: ResolvedOp | null): op is ResolvedChildOp => {
  return !!(op && 'ChildOp' in op);
};

export const isResolvedLockOp = (op?: ResolvedOp | null): op is ResolvedLockOp => {
  return !!(op && 'LockOp' in op);
};

export const isResolvedUnlockOp = (op?: ResolvedOp | null): op is ResolvedUnlockOp => {
  return !!(op && 'UnlockOp' in op);
};

export const isResolvedBlockOp = (op?: ResolvedOp | null): op is GBlock<ResolvedBlock> => {
  return isResolvedBlock(op as ResolvedOperation); //TODO: Fix contract-kit types
};

export const isResolvedStoreOp = (op?: ResolvedOp | null): op is GStore<CwebStore> => {
  return isResolvedStore(op as ResolvedOperation); //TODO: Fix contract-kit types
};

export const isResolvedCallOp = (op?: ResolvedOp | null): op is GCall<CwebCallRefResolved> => {
  return isResolvedCall(op as ResolvedOperation); //TODO: Fix contract-kit types
};

export const isResolvedTakeOp = (op?: ResolvedOp | null): op is GTake<ResolvedTake> => {
  return isResolvedTake(op as ResolvedOperation); //TODO: Fix contract-kit types
};

export const isResolvedReadOp = (op?: ResolvedOp | null): op is GRead<ResolvedRead> => {
  return isResolvedRead(op as ResolvedOperation); //TODO: Fix contract-kit types
};

export const isPreparedExecOp = (op?: PreparedOp | null): op is PreparedExecOp => {
  return !!(op && 'ExecOp' in op);
};

export const isPreparedBlockOp = (op?: PreparedOp | null): op is GBlock<CwebBlock> => {
  return !!(op && 'BlockOp' in op);
};

export const isPreparedLockOp = (op?: PreparedOp | null): op is PreparedLockOp => {
  return !!(op && 'LockOp' in op);
};

export const isPreparedUnlockOp = (op?: PreparedOp | null): op is PreparedUnlockOp => {
  return !!(op && 'UnlockOp' in op);
};

export const isPreparedStoreOp = (op?: PreparedOp | null): op is GStore<CwebStore> => {
  return !!(op && 'StoreOp' in op);
};

export const isPreparedExtendedStoreOp = (op?: PreparedOp | null): op is PreparedExtendedStoreOp => {
  return !!(op && 'StoreOp' in op);
};

export const isPreparedTakeOp = (op?: PreparedOp | null): op is GTake<CwebTake> => {
  return !!(op && 'TakeOp' in op);
};
