package build

import (
	"golang.org/x/xerrors"

	"github.com/filecoin-project/go-state-types/abi"
	"github.com/filecoin-project/go-state-types/network"
)

func SealProofTypeFromSectorSize(ssize abi.SectorSize, nv network.Version) (abi.RegisteredSealProof, error) {
	switch {
	case nv < network.Version7:
		switch ssize {
		case 2 << 10:
			return abi.RegisteredSealProof_StackedDrg2KiBV1, nil
		case 8 << 20:
			return abi.RegisteredSealProof_StackedDrg8MiBV1, nil
		case 16 << 20:
			return abi.RegisteredSealProof_StackedDrg16MiBV1, nil
		case 32 << 20:
			return abi.RegisteredSealProof_StackedDrg32MiBV1, nil
		case 64 << 20:
			return abi.RegisteredSealProof_StackedDrg64MiBV1, nil
		case 128 << 20:
			return abi.RegisteredSealProof_StackedDrg128MiBV1, nil
		case 256 << 20:
			return abi.RegisteredSealProof_StackedDrg256MiBV1, nil
		case 512 << 20:
			return abi.RegisteredSealProof_StackedDrg512MiBV1, nil
		case 32 << 30:
			return abi.RegisteredSealProof_StackedDrg32GiBV1, nil
		case 64 << 30:
			return abi.RegisteredSealProof_StackedDrg64GiBV1, nil
		default:
			return 0, xerrors.Errorf("unsupported sector size for miner: %v", ssize)
		}
	case nv >= network.Version7:
		switch ssize {
		case 2 << 10:
			return abi.RegisteredSealProof_StackedDrg2KiBV1_1, nil
		case 8 << 20:
			return abi.RegisteredSealProof_StackedDrg8MiBV1_1, nil
		case 16 << 20:
			return abi.RegisteredSealProof_StackedDrg16MiBV1_1, nil
		case 32 << 20:
			return abi.RegisteredSealProof_StackedDrg32MiBV1_1, nil
		case 64 << 20:
			return abi.RegisteredSealProof_StackedDrg64MiBV1_1, nil
		case 128 << 20:
			return abi.RegisteredSealProof_StackedDrg128MiBV1_1, nil
		case 256 << 20:
			return abi.RegisteredSealProof_StackedDrg256MiBV1_1, nil
		case 512 << 20:
			return abi.RegisteredSealProof_StackedDrg512MiBV1_1, nil
		case 32 << 30:
			return abi.RegisteredSealProof_StackedDrg32GiBV1_1, nil
		case 64 << 30:
			return abi.RegisteredSealProof_StackedDrg64GiBV1_1, nil
		default:
			return 0, xerrors.Errorf("unsupported sector size for miner: %v", ssize)
		}
	}

	return 0, xerrors.Errorf("unsupported network version")
}

func PreferredSealProofTypeFromWindowPoStType(nver network.Version, proof abi.RegisteredPoStProof) (abi.RegisteredSealProof, error) {
	// We added support for the new proofs in network version 7, and removed support for the old
	// ones in network version 8.
	if nver < network.Version7 {
		switch proof {
		case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1:
			return abi.RegisteredSealProof_StackedDrg2KiBV1, nil
		case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1:
			return abi.RegisteredSealProof_StackedDrg8MiBV1, nil
		case abi.RegisteredPoStProof_StackedDrgWindow16MiBV1:
			return abi.RegisteredSealProof_StackedDrg16MiBV1, nil
		case abi.RegisteredPoStProof_StackedDrgWindow32MiBV1:
			return abi.RegisteredSealProof_StackedDrg32MiBV1, nil
		case abi.RegisteredPoStProof_StackedDrgWindow64MiBV1:
			return abi.RegisteredSealProof_StackedDrg64MiBV1, nil
		case abi.RegisteredPoStProof_StackedDrgWindow128MiBV1:
			return abi.RegisteredSealProof_StackedDrg128MiBV1, nil
		case abi.RegisteredPoStProof_StackedDrgWindow256MiBV1:
			return abi.RegisteredSealProof_StackedDrg256MiBV1, nil
		case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1:
			return abi.RegisteredSealProof_StackedDrg512MiBV1, nil
		case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1:
			return abi.RegisteredSealProof_StackedDrg32GiBV1, nil
		case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1:
			return abi.RegisteredSealProof_StackedDrg64GiBV1, nil
		default:
			return -1, xerrors.Errorf("unrecognized window post type: %d", proof)
		}
	}

	switch proof {
	case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1:
		return abi.RegisteredSealProof_StackedDrg2KiBV1_1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1:
		return abi.RegisteredSealProof_StackedDrg8MiBV1_1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow16MiBV1:
		return abi.RegisteredSealProof_StackedDrg16MiBV1_1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow32MiBV1:
		return abi.RegisteredSealProof_StackedDrg32MiBV1_1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow64MiBV1:
		return abi.RegisteredSealProof_StackedDrg64MiBV1_1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow128MiBV1:
		return abi.RegisteredSealProof_StackedDrg128MiBV1_1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow256MiBV1:
		return abi.RegisteredSealProof_StackedDrg256MiBV1_1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1:
		return abi.RegisteredSealProof_StackedDrg512MiBV1_1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1:
		return abi.RegisteredSealProof_StackedDrg32GiBV1_1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1:
		return abi.RegisteredSealProof_StackedDrg64GiBV1_1, nil
	default:
		return -1, xerrors.Errorf("unrecognized window post type: %d", proof)
	}
}

func WinningPoStProofTypeFromWindowPoStProofType(nver network.Version, proof abi.RegisteredPoStProof) (abi.RegisteredPoStProof, error) {
	switch proof {
	case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1:
		return abi.RegisteredPoStProof_StackedDrgWinning2KiBV1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1:
		return abi.RegisteredPoStProof_StackedDrgWinning8MiBV1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow16MiBV1:
		return abi.RegisteredPoStProof_StackedDrgWinning16MiBV1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow32MiBV1:
		return abi.RegisteredPoStProof_StackedDrgWinning32MiBV1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow64MiBV1:
		return abi.RegisteredPoStProof_StackedDrgWinning64MiBV1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow128MiBV1:
		return abi.RegisteredPoStProof_StackedDrgWinning128MiBV1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow256MiBV1:
		return abi.RegisteredPoStProof_StackedDrgWinning256MiBV1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1:
		return abi.RegisteredPoStProof_StackedDrgWinning512MiBV1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1:
		return abi.RegisteredPoStProof_StackedDrgWinning32GiBV1, nil
	case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1:
		return abi.RegisteredPoStProof_StackedDrgWinning64GiBV1, nil
	default:
		return -1, xerrors.Errorf("unknown proof type %d", proof)
	}
}