class IcebergTableName {

    public static IcebergTableName from(String name)
    {
        Matcher match = TABLE_PATTERN.matcher(name);
        if (!match.matches()) {
            throw new PrestoException(NOT_SUPPORTED, "Invalid Iceberg table name: " + name);
        }

        String table = match.group("table");
        String typeString = match.group("type");
        String ver1 = match.group("ver1");
        String ver2 = match.group("ver2");

        TableType type = TableType.DATA;
        if (typeString != null) {
            try {
                type = TableType.valueOf(typeString.toUpperCase(Locale.ROOT));
            }
            catch (IllegalArgumentException e) {
                throw new PrestoException(NOT_SUPPORTED, format("Invalid Iceberg table name (unknown type '%s'): %s", typeString, name));
            }
        }

        Optional<Long> version = Optional.empty();
        if (type == TableType.DATA || type == TableType.PARTITIONS || type == TableType.MANIFESTS || type == TableType.FILES) {
            if (ver1 != null && ver2 != null) {
                throw new PrestoException(NOT_SUPPORTED, "Invalid Iceberg table name (cannot specify two @ versions): " + name);
            }
            if (ver1 != null) {
                version = Optional.of(parseLong(ver1));
            }
            else if (ver2 != null) {
                version = Optional.of(parseLong(ver2));
            }
        }
        else if (ver1 != null || ver2 != null) {
            throw new PrestoException(NOT_SUPPORTED, format("Invalid Iceberg table name (cannot use @ version with table type '%s'): %s", type, name));
        }

        return new IcebergTableName(table, type, version);
    }

    public  IcebergTableName(String tableName, TableType tableType, Optional<Long> snapshotId);

}