// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package iceberg

import (
	
	
	
	
)

// ParseTransform takes the string representation of a transform as
// defined in the iceberg spec, and produces the appropriate Transform
// object or an error if the string is not a valid transform string.
func ( string) (Transform, error) {
	 = strings.ToLower()
	switch {
	case strings.HasPrefix(, "bucket"):
		 := regexFromBrackets.FindStringSubmatch()
		if len() != 2 {
			break
		}

		,  := strconv.Atoi([1])
		return BucketTransform{NumBuckets: }, nil
	case strings.HasPrefix(, "truncate"):
		 := regexFromBrackets.FindStringSubmatch()
		if len() != 2 {
			break
		}

		,  := strconv.Atoi([1])
		return TruncateTransform{Width: }, nil
	default:
		switch  {
		case "identity":
			return IdentityTransform{}, nil
		case "void":
			return VoidTransform{}, nil
		case "year":
			return YearTransform{}, nil
		case "month":
			return MonthTransform{}, nil
		case "day":
			return DayTransform{}, nil
		case "hour":
			return HourTransform{}, nil
		}
	}

	return nil, fmt.Errorf("%w: %s", ErrInvalidTransform, )
}

// Transform is an interface for the various Transformation types
// in partition specs. Currently, they do not yet provide actual
// transformation functions or implementation. That will come later as
// data reading gets implemented.
type Transform interface {
	fmt.Stringer
	encoding.TextMarshaler
	ResultType(t Type) Type
}

// IdentityTransform uses the identity function, performing no transformation
// but instead partitioning on the value itself.
type IdentityTransform struct{}

func ( IdentityTransform) () ([]byte, error) {
	return []byte(.String()), nil
}

func (IdentityTransform) () string { return "identity" }

func (IdentityTransform) ( Type) Type { return  }

// VoidTransform is a transformation that always returns nil.
type VoidTransform struct{}

func ( VoidTransform) () ([]byte, error) {
	return []byte(.String()), nil
}

func (VoidTransform) () string { return "void" }

func (VoidTransform) ( Type) Type { return  }

// BucketTransform transforms values into a bucket partition value. It is
// parameterized by a number of buckets. Bucket partition transforms use
// a 32-bit hash of the source value to produce a positive value by mod
// the bucket number.
type BucketTransform struct {
	NumBuckets int
}

func ( BucketTransform) () ([]byte, error) {
	return []byte(.String()), nil
}

func ( BucketTransform) () string { return fmt.Sprintf("bucket[%d]", .NumBuckets) }

func (BucketTransform) (Type) Type { return PrimitiveTypes.Int32 }

// TruncateTransform is a transformation for truncating a value to a specified width.
type TruncateTransform struct {
	Width int
}

func ( TruncateTransform) () ([]byte, error) {
	return []byte(.String()), nil
}

func ( TruncateTransform) () string { return fmt.Sprintf("truncate[%d]", .Width) }

func (TruncateTransform) ( Type) Type { return  }

// YearTransform transforms a datetime value into a year value.
type YearTransform struct{}

func ( YearTransform) () ([]byte, error) {
	return []byte(.String()), nil
}

func (YearTransform) () string { return "year" }

func (YearTransform) (Type) Type { return PrimitiveTypes.Int32 }

// MonthTransform transforms a datetime value into a month value.
type MonthTransform struct{}

func ( MonthTransform) () ([]byte, error) {
	return []byte(.String()), nil
}

func (MonthTransform) () string { return "month" }

func (MonthTransform) (Type) Type { return PrimitiveTypes.Int32 }

// DayTransform transforms a datetime value into a date value.
type DayTransform struct{}

func ( DayTransform) () ([]byte, error) {
	return []byte(.String()), nil
}

func (DayTransform) () string { return "day" }

func (DayTransform) (Type) Type { return PrimitiveTypes.Date }

// HourTransform transforms a datetime value into an hour value.
type HourTransform struct{}

func ( HourTransform) () ([]byte, error) {
	return []byte(.String()), nil
}

func (HourTransform) () string { return "hour" }

func (HourTransform) (Type) Type { return PrimitiveTypes.Int32 }