// Code generated by entc, DO NOT EDIT.

package ent

import (
	"encoding/json"
	"fmt"
	"strings"
	"time"

	"entgo.io/ent/dialect/sql"

	"github.com/pingcap/test-infra/common/model"
	"github.com/pingcap/test-infra/services/tcms/service/store/v2/ent/testbedinfo"
)

// TestbedInfo is the model entity for the TestbedInfo schema.
type TestbedInfo struct {
	config `json:"-"`
	// ID of the ent.
	ID model.ID `json:"id,omitempty"`
	// CreatedAt holds the value of the "createdAt" field.
	CreatedAt time.Time `json:"createdAt,omitempty"`
	// UpdatedAt holds the value of the "updatedAt" field.
	UpdatedAt time.Time `json:"updatedAt,omitempty"`
	// Name holds the value of the "name" field.
	Name string `json:"name,omitempty"`
	// Status holds the value of the "status" field.
	Status model.TestBedInfoStatus `json:"status,omitempty"`
	// PlanExecutionID holds the value of the "planExecutionID" field.
	PlanExecutionID model.ID `json:"planExecutionID,omitempty"`
	// URL holds the value of the "url" field.
	// URL to the testbed
	URL string `json:"url,omitempty"`
	// LeaseDDL holds the value of the "leaseDDL" field.
	// The timestamp when a testbed will be released.
	LeaseDDL *time.Time `json:"leaseDDL,omitempty"`
	// InitiatedAt holds the value of the "initiatedAt" field.
	InitiatedAt *time.Time `json:"initiatedAt,omitempty"`
	// ReleasedAt holds the value of the "releasedAt" field.
	ReleasedAt *time.Time `json:"releasedAt,omitempty"`
	// ReleasedBy holds the value of the "releasedBy" field.
	ReleasedBy *model.ID `json:"releasedBy,omitempty"`
	// PhysicalResourceRequest holds the value of the "physicalResourceRequest" field.
	PhysicalResourceRequest model.PhysicalResource `json:"physicalResourceRequest,omitempty"`
	// ResourceItems holds the value of the "resourceItems" field.
	ResourceItems []model.TestBedInfoResourceItem `json:"resourceItems,omitempty"`
	// Type holds the value of the "type" field.
	Type model.TestBedInfoType `json:"type,omitempty"`
	// SetUpLogURL holds the value of the "setUpLogURL" field.
	// URL to the testbed setup log
	SetUpLogURL string `json:"setUpLogURL,omitempty"`
	// ResourcePoolID holds the value of the "resourcePoolID" field.
	ResourcePoolID model.ID `json:"resourcePoolID,omitempty"`
}

// scanValues returns the types for scanning values from sql.Rows.
func (*TestbedInfo) scanValues(columns []string) ([]interface{}, error) {
	values := make([]interface{}, len(columns))
	for i := range columns {
		switch columns[i] {
		case testbedinfo.FieldPhysicalResourceRequest, testbedinfo.FieldResourceItems:
			values[i] = new([]byte)
		case testbedinfo.FieldID, testbedinfo.FieldPlanExecutionID, testbedinfo.FieldReleasedBy, testbedinfo.FieldResourcePoolID:
			values[i] = new(sql.NullInt64)
		case testbedinfo.FieldName, testbedinfo.FieldStatus, testbedinfo.FieldURL, testbedinfo.FieldType, testbedinfo.FieldSetUpLogURL:
			values[i] = new(sql.NullString)
		case testbedinfo.FieldCreatedAt, testbedinfo.FieldUpdatedAt, testbedinfo.FieldLeaseDDL, testbedinfo.FieldInitiatedAt, testbedinfo.FieldReleasedAt:
			values[i] = new(sql.NullTime)
		default:
			return nil, fmt.Errorf("unexpected column %q for type TestbedInfo", columns[i])
		}
	}
	return values, nil
}

// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the TestbedInfo fields.
func (ti *TestbedInfo) assignValues(columns []string, values []interface{}) error {
	if m, n := len(values), len(columns); m < n {
		return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
	}
	for i := range columns {
		switch columns[i] {
		case testbedinfo.FieldID:
			value, ok := values[i].(*sql.NullInt64)
			if !ok {
				return fmt.Errorf("unexpected type %T for field id", value)
			}
			ti.ID = model.ID(value.Int64)
		case testbedinfo.FieldCreatedAt:
			if value, ok := values[i].(*sql.NullTime); !ok {
				return fmt.Errorf("unexpected type %T for field createdAt", values[i])
			} else if value.Valid {
				ti.CreatedAt = value.Time
			}
		case testbedinfo.FieldUpdatedAt:
			if value, ok := values[i].(*sql.NullTime); !ok {
				return fmt.Errorf("unexpected type %T for field updatedAt", values[i])
			} else if value.Valid {
				ti.UpdatedAt = value.Time
			}
		case testbedinfo.FieldName:
			if value, ok := values[i].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field name", values[i])
			} else if value.Valid {
				ti.Name = value.String
			}
		case testbedinfo.FieldStatus:
			if value, ok := values[i].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field status", values[i])
			} else if value.Valid {
				ti.Status = model.TestBedInfoStatus(value.String)
			}
		case testbedinfo.FieldPlanExecutionID:
			if value, ok := values[i].(*sql.NullInt64); !ok {
				return fmt.Errorf("unexpected type %T for field planExecutionID", values[i])
			} else if value.Valid {
				ti.PlanExecutionID = model.ID(value.Int64)
			}
		case testbedinfo.FieldURL:
			if value, ok := values[i].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field url", values[i])
			} else if value.Valid {
				ti.URL = value.String
			}
		case testbedinfo.FieldLeaseDDL:
			if value, ok := values[i].(*sql.NullTime); !ok {
				return fmt.Errorf("unexpected type %T for field leaseDDL", values[i])
			} else if value.Valid {
				ti.LeaseDDL = new(time.Time)
				*ti.LeaseDDL = value.Time
			}
		case testbedinfo.FieldInitiatedAt:
			if value, ok := values[i].(*sql.NullTime); !ok {
				return fmt.Errorf("unexpected type %T for field initiatedAt", values[i])
			} else if value.Valid {
				ti.InitiatedAt = new(time.Time)
				*ti.InitiatedAt = value.Time
			}
		case testbedinfo.FieldReleasedAt:
			if value, ok := values[i].(*sql.NullTime); !ok {
				return fmt.Errorf("unexpected type %T for field releasedAt", values[i])
			} else if value.Valid {
				ti.ReleasedAt = new(time.Time)
				*ti.ReleasedAt = value.Time
			}
		case testbedinfo.FieldReleasedBy:
			if value, ok := values[i].(*sql.NullInt64); !ok {
				return fmt.Errorf("unexpected type %T for field releasedBy", values[i])
			} else if value.Valid {
				ti.ReleasedBy = new(model.ID)
				*ti.ReleasedBy = model.ID(value.Int64)
			}
		case testbedinfo.FieldPhysicalResourceRequest:
			if value, ok := values[i].(*[]byte); !ok {
				return fmt.Errorf("unexpected type %T for field physicalResourceRequest", values[i])
			} else if value != nil && len(*value) > 0 {
				if err := json.Unmarshal(*value, &ti.PhysicalResourceRequest); err != nil {
					return fmt.Errorf("unmarshal field physicalResourceRequest: %w", err)
				}
			}
		case testbedinfo.FieldResourceItems:
			if value, ok := values[i].(*[]byte); !ok {
				return fmt.Errorf("unexpected type %T for field resourceItems", values[i])
			} else if value != nil && len(*value) > 0 {
				if err := json.Unmarshal(*value, &ti.ResourceItems); err != nil {
					return fmt.Errorf("unmarshal field resourceItems: %w", err)
				}
			}
		case testbedinfo.FieldType:
			if value, ok := values[i].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field type", values[i])
			} else if value.Valid {
				ti.Type = model.TestBedInfoType(value.String)
			}
		case testbedinfo.FieldSetUpLogURL:
			if value, ok := values[i].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field setUpLogURL", values[i])
			} else if value.Valid {
				ti.SetUpLogURL = value.String
			}
		case testbedinfo.FieldResourcePoolID:
			if value, ok := values[i].(*sql.NullInt64); !ok {
				return fmt.Errorf("unexpected type %T for field resourcePoolID", values[i])
			} else if value.Valid {
				ti.ResourcePoolID = model.ID(value.Int64)
			}
		}
	}
	return nil
}

// Update returns a builder for updating this TestbedInfo.
// Note that you need to call TestbedInfo.Unwrap() before calling this method if this TestbedInfo
// was returned from a transaction, and the transaction was committed or rolled back.
func (ti *TestbedInfo) Update() *TestbedInfoUpdateOne {
	return (&TestbedInfoClient{config: ti.config}).UpdateOne(ti)
}

// Unwrap unwraps the TestbedInfo entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (ti *TestbedInfo) Unwrap() *TestbedInfo {
	tx, ok := ti.config.driver.(*txDriver)
	if !ok {
		panic("ent: TestbedInfo is not a transactional entity")
	}
	ti.config.driver = tx.drv
	return ti
}

// String implements the fmt.Stringer.
func (ti *TestbedInfo) String() string {
	var builder strings.Builder
	builder.WriteString("TestbedInfo(")
	builder.WriteString(fmt.Sprintf("id=%v", ti.ID))
	builder.WriteString(", createdAt=")
	builder.WriteString(ti.CreatedAt.Format(time.ANSIC))
	builder.WriteString(", updatedAt=")
	builder.WriteString(ti.UpdatedAt.Format(time.ANSIC))
	builder.WriteString(", name=")
	builder.WriteString(ti.Name)
	builder.WriteString(", status=")
	builder.WriteString(fmt.Sprintf("%v", ti.Status))
	builder.WriteString(", planExecutionID=")
	builder.WriteString(fmt.Sprintf("%v", ti.PlanExecutionID))
	builder.WriteString(", url=")
	builder.WriteString(ti.URL)
	if v := ti.LeaseDDL; v != nil {
		builder.WriteString(", leaseDDL=")
		builder.WriteString(v.Format(time.ANSIC))
	}
	if v := ti.InitiatedAt; v != nil {
		builder.WriteString(", initiatedAt=")
		builder.WriteString(v.Format(time.ANSIC))
	}
	if v := ti.ReleasedAt; v != nil {
		builder.WriteString(", releasedAt=")
		builder.WriteString(v.Format(time.ANSIC))
	}
	if v := ti.ReleasedBy; v != nil {
		builder.WriteString(", releasedBy=")
		builder.WriteString(fmt.Sprintf("%v", *v))
	}
	builder.WriteString(", physicalResourceRequest=")
	builder.WriteString(fmt.Sprintf("%v", ti.PhysicalResourceRequest))
	builder.WriteString(", resourceItems=")
	builder.WriteString(fmt.Sprintf("%v", ti.ResourceItems))
	builder.WriteString(", type=")
	builder.WriteString(fmt.Sprintf("%v", ti.Type))
	builder.WriteString(", setUpLogURL=")
	builder.WriteString(ti.SetUpLogURL)
	builder.WriteString(", resourcePoolID=")
	builder.WriteString(fmt.Sprintf("%v", ti.ResourcePoolID))
	builder.WriteByte(')')
	return builder.String()
}

// TestbedInfos is a parsable slice of TestbedInfo.
type TestbedInfos []*TestbedInfo

func (ti TestbedInfos) config(cfg config) {
	for _i := range ti {
		ti[_i].config = cfg
	}
}
