// extractWorkItemTypeFields extracts the field information for a wit; it returns slices for
// field labels and field keys
557540
func extractWorkItemTypeFields(wit workitem.WorkItemType) ([]string, []string, error) {
	fieldLabels := []string{}
	fieldKeys := []string{}
	for fieldKey, fieldDefinition := range wit.Fields {
		// extract the label and key
		fieldLabels = append(fieldLabels, fieldDefinition.Label)
		fieldKeys = append(fieldKeys, fieldKey)
	}
	return fieldLabels, fieldKeys, nil
}
695550
func (wit WorkItemType) ConvertWorkItemStorageToModel(workItem WorkItemStorage) (*WorkItem, error) {
	result := WorkItem{
		ID:                     workItem.ID,
		Number:                 workItem.Number,
		Type:                   workItem.Type,
		Version:                workItem.Version,
		Fields:                 map[string]interface{}{},
		SpaceID:                workItem.SpaceID,
		relationShipsChangedAt: workItem.RelationShipsChangedAt,
	}

	for name, field := range wit.Fields {
		var err error
		if name == SystemCreatedAt {
			continue
		}
		result.Fields[name], err = field.ConvertFromModel(name, workItem.Fields[name])
		if err != nil {
			return nil, errs.WithStack(err)
		}
		result.Fields[SystemOrder] = workItem.ExecutionOrder
	}

	return &result, nil
}
462451
func cachedTypeFields(t reflect.Type) []field {
	if f, ok := fieldCache.Load(t); ok {
		return f.([]field)
	}
	f, _ := fieldCache.LoadOrStore(t, typeFields(t))
	return f.([]field)
}
239351
func (s *StartJobRunInput) SetWorkerType(v string) *StartJobRunInput {
	s.WorkerType = &v
	return s
}
563785
func (r *GormWorkItemRepository) ChangeWorkItemType(ctx context.Context, wiStorage *WorkItemStorage, oldWIType *WorkItemType, newWIType *WorkItemType, spaceID uuid.UUID) error {
	allowedWIT, err := r.CheckTypeAndSpaceShareTemplate(ctx, newWIType, spaceID)
	if err != nil {
		return errs.Wrap(err, "failed to check workitem type")
	}
	if !allowedWIT {
		return errors.NewBadParameterError("typeID", oldWIType.ID)
	}
	var fieldDiff = Fields{}
	// Loop through old workitem type
	for oldFieldName, oldFieldDef := range oldWIType.Fields {
		// Temporary workaround to not add metastates to the field diff. We need
		// to have a special handling for fields that shouldn't be set by user
		// (or affected by type change) MetaState is a system level detail and
		// that shouldn't be affected by type change, even if it is affected, it
		// shouldn't show up in the field diff. The purpose of
		// fieldDiff is to get the list of fields that should be added to the
		// description. Metastate shouldn't show up in the description
		if oldFieldName == SystemMetaState {
			continue
		}
		// The field exists in old type and new type
		if newField, ok := newWIType.Fields[oldFieldName]; ok {
			newVal, err := oldFieldDef.Type.ConvertToModelWithType(newField.Type, wiStorage.Fields[oldFieldName])
			if err == nil {
				wiStorage.Fields[oldFieldName] = newVal
			}
			// Failed to assign the old value to the new field. Add the field to
			// the diff and remove it from the old workitem.
			if err != nil {
				fieldDiff[oldFieldName] = wiStorage.Fields[oldFieldName]
				delete(wiStorage.Fields, oldFieldName)
			}
		} else { // field doesn't exist in new type
			if wiStorage.Fields[oldFieldName] != nil {
				fieldDiff[oldFieldName] = wiStorage.Fields[oldFieldName]
				delete(wiStorage.Fields, oldFieldName)
			}
		}
	}
	// We need fieldKeys to show field diff in a defined order. Golang maps
	// aren't ordered by default.
	var fieldKeys []string
	for fieldName := range fieldDiff {
		fieldKeys = append(fieldKeys, fieldName)
	}
	// Sort the field keys to prevent random order of fields
	sort.Strings(fieldKeys)
	// Append diff (fields along with their values) between the workitem types
	// to the description
	if len(fieldDiff) > 0 {
		// If description doesn't exists, assign it empty value
		if wiStorage.Fields[SystemDescription] == nil {
			wiStorage.Fields[SystemDescription] = ""
		}
		originalDescription := rendering.NewMarkupContentFromValue(wiStorage.Fields[SystemDescription])
		// TemplateData holds the information to be added to the description
		templateData := struct {
			NewTypeName         string
			FieldNameValues     map[string]string
			OriginalDescription string
		}{
			NewTypeName:         newWIType.Name,
			FieldNameValues:     make(map[string]string),
			OriginalDescription: originalDescription.Content,
		}

		for _, fieldName := range fieldKeys {
			fieldDef := oldWIType.Fields[fieldName]
			oldKind := fieldDef.Type.GetKind()
			oldValue := fieldDiff[fieldName]

			if oldKind == KindEnum {
				enumType, ok := fieldDef.Type.(EnumType)
				if !ok {
					return errs.Errorf("failed to convert field %q to enum type: %+v", fieldName, fieldDef)
				}
				oldKind = enumType.BaseType.GetKind()
			}
			// handle all single value fields (including Enums)
			if oldKind != KindList {
				var val string
				if oldKind.IsRelational() {
					val, err = getValueOfRelationalKind(r.db, oldValue, oldKind)
					if err != nil {
						return errs.Wrapf(err, "failed to get relational value for field %s", fieldName)
					}
				} else {
					val = fmt.Sprint(oldValue)
				}
				// Add field information to the description
				templateData.FieldNameValues[oldWIType.Fields[fieldName].Label] = val
				continue
			}

			// Deal with multi value field (KindList)
			listType, ok := fieldDef.Type.(ListType)
			if !ok {
				return errs.Errorf("failed to convert field %q to list type: %+v", fieldName, fieldDef)
			}
			oldKind = listType.ComponentType.GetKind()
			valList, ok := fieldDiff[fieldName].([]interface{})
			if !ok {
				return errs.Errorf("failed to convert list value of field %q to []interface{}: %+v", fieldName, fieldDiff[fieldName])
			}

			var tempList []string
			for _, v := range valList {
				val := fmt.Sprint(v)
				if oldKind.IsRelational() {
					val, err = getValueOfRelationalKind(r.db, v, oldKind)
					if err != nil {
						return errs.Wrapf(err, "failed to get relational value for field %s", fieldName)
					}
				}
				tempList = append(tempList, val)
			}
			// Convert []string to comma seperated strings and add it to the
			// description.
			templateData.FieldNameValues[oldWIType.Fields[fieldName].Label] = strings.Join(tempList, ", ")
		}
		descriptionTemplate := template.Must(template.New("test").Parse("```" +
			`
Missing fields in workitem type: {{ .NewTypeName }}
{{range $index, $element := .FieldNameValues }}
{{$index}} : {{$element}}{{end}}
` + "```" + `
{{.OriginalDescription}}
`))
		var newDescription bytes.Buffer
		if err := descriptionTemplate.Execute(&newDescription, templateData); err != nil {
			return errs.Wrap(err, "failed to populate description template")
		}
		wiStorage.Fields[SystemDescription] = rendering.NewMarkupContent(newDescription.String(), rendering.SystemMarkupMarkdown)
	}
	// Set default values for all field in newWIType
	for fieldName, fieldDef := range newWIType.Fields {
		fieldValue := wiStorage.Fields[fieldName]
		// Do not assign default value to metastate
		if fieldName == SystemMetaState {
			continue
		}
		// Assign default only if fieldValue is nil
		wiStorage.Fields[fieldName], err = fieldDef.ConvertToModel(fieldName, fieldValue)
		if err != nil {
			return errs.Wrapf(err, "failed to convert field %q", fieldName)
		}
	}
	wiStorage.Type = newWIType.ID
	return nil
}
838773
func (c *WorkItemTypeGroupsController) List(ctx *app.ListWorkItemTypeGroupsContext) error {
	var typeGroups []*workitem.WorkItemTypeGroup
	err := application.Transactional(c.db, func(appl application.Application) error {
		list, err := appl.WorkItemTypeGroups().List(ctx, ctx.SpaceTemplateID)
		if err != nil {
			return errs.WithStack(err)
		}
		typeGroups = list
		return nil
	})
	if err != nil {
		return jsonapi.JSONErrorResponse(ctx, err)
	}
	res := &app.WorkItemTypeGroupList{
		Data: make([]*app.WorkItemTypeGroupData, len(typeGroups)),
		Links: &app.WorkItemTypeGroupLinks{
			Self: rest.AbsoluteURL(ctx.Request, app.SpaceTemplateHref(ctx.SpaceTemplateID)) + "/" + APIWorkItemTypeGroups,
		},
	}
	for i, group := range typeGroups {
		res.Data[i] = ConvertTypeGroup(ctx.Request, *group)
	}
	return ctx.OK(res)
}
1135877
func ExtractQueryType(opts ...interface{}) *opt.QueryTypeOption {
	for _, o := range opts {
		if v, ok := o.(*opt.QueryTypeOption); ok {
			return v
		}
	}
	return nil
}
89464
func (wit WorkItemType) Validate() error {
	if strings.TrimSpace(wit.Name) == "" {
		return errs.Errorf(`work item type name "%s" when trimmed has a zero-length`, wit.Name)
	}
	if err := wit.Fields.Validate(); err != nil {
		return errs.Wrapf(err, "failed to validate work item type's fields")
	}
	return nil
}
763434
func ConvertTypeGroup(request *http.Request, tg workitem.WorkItemTypeGroup) *app.WorkItemTypeGroupData {
	workitemtypes := "workitemtypes"
	workItemTypeGroupRelatedURL := rest.AbsoluteURL(request, app.WorkItemTypeGroupHref(tg.ID))
	createdAt := tg.CreatedAt.UTC()
	updatedAt := tg.UpdatedAt.UTC()
	// Every work item type group except the one in the "iteration" bucket are
	// meant to be shown in the sidebar.
	showInSidebar := (tg.Bucket != workitem.BucketIteration)

	res := &app.WorkItemTypeGroupData{
		ID:   &tg.ID,
		Type: APIWorkItemTypeGroups,
		Links: &app.GenericLinks{
			Related: &workItemTypeGroupRelatedURL,
		},
		Attributes: &app.WorkItemTypeGroupAttributes{
			Bucket:        tg.Bucket.String(),
			Name:          tg.Name,
			Description:   tg.Description,
			Icon:          tg.Icon,
			CreatedAt:     &createdAt,
			UpdatedAt:     &updatedAt,
			ShowInSidebar: &showInSidebar,
		},
		Relationships: &app.WorkItemTypeGroupRelationships{
			TypeList: &app.RelationGenericList{
				Data: make([]*app.GenericData, len(tg.TypeList)),
			},
			SpaceTemplate: &app.RelationGeneric{
				Data: &app.GenericData{
					ID:   ptr.String(tg.SpaceTemplateID.String()),
					Type: &APISpaceTemplates,
				},
			},
		},
	}

	for i, witID := range tg.TypeList {
		// witRelatedURL := rest.AbsoluteURL(request, app.WorkitemtypeHref(space.SystemSpace, witID))
		idStr := witID.String()
		res.Relationships.TypeList.Data[i] = &app.GenericData{
			ID:   &idStr,
			Type: &workitemtypes,
			// Links: &app.GenericLinks{
			// Related: &witRelatedURL,
			// },
		}
	}
	return res
}
1180775
func workItemIncludeCommentsAndTotal(ctx context.Context, db application.DB, parentID uuid.UUID) WorkItemConvertFunc {
	// TODO: Wrap ctx in a Timeout context?
	count := make(chan int)
	go func() {
		defer close(count)
		application.Transactional(db, func(appl application.Application) error {
			cs, err := appl.Comments().Count(ctx, parentID)
			if err != nil {
				count <- 0
				return errs.WithStack(err)
			}
			count <- cs
			return nil
		})
	}()
	return func(request *http.Request, wi *workitem.WorkItem, wi2 *app.WorkItem) error {
		wi2.Relationships.Comments = CreateCommentsRelation(request, wi)
		wi2.Relationships.Comments.Meta = map[string]interface{}{
			"totalCount": <-count,
		}
		return nil
	}
}
95115
func (c *CloudPersister) ListItemTypes() ([]*types.ItemType, error) {
	ctx := context.Background()
	ItemTypes := make([]*types.ItemType, 0)
	q := datastore.NewQuery("ItemType")

	keys, err := c.DatastoreClient().GetAll(ctx, q, &ItemTypes)

	if err != nil {
		return nil, fmt.Errorf("datastoredb: could not list ItemTypes: %v", err)
	}

	for i, k := range keys {
		ItemTypes[i].ID = k.ID()
	}

	return ItemTypes, nil
}
869164
func (r Account_Shipment_Item) GetShipmentItemType() (resp datatypes.Account_Shipment_Item_Type, err error) {
	err = r.Session.DoRequest("SoftLayer_Account_Shipment_Item", "getShipmentItemType", nil, &r.Options, &resp)
	return
}
451037
func (r *GormWorkItemTypeRepository) loadChildTypeList(ctx context.Context, parentTypeID uuid.UUID) ([]uuid.UUID, error) {
	types := []ChildType{}
	db := r.db.Model(&types).Where("parent_work_item_type_id=?", parentTypeID).Order("position ASC").Find(&types)
	if db.RecordNotFound() {
		log.Error(ctx, map[string]interface{}{"wit_id": parentTypeID}, "work item type child types not found")
		return nil, errors.NewNotFoundError("work item type child types", parentTypeID.String())
	}
	if err := db.Error; err != nil {
		return nil, errors.NewInternalError(ctx, err)
	}
	res := make([]uuid.UUID, len(types))
	for i, childType := range types {
		res[i] = childType.ChildWorkItemTypeID
	}
	return res, nil
}
922861
func validateWorkflowFieldNames(slice interface{}) error {
	s := reflect.ValueOf(slice)
	if s.Kind() != reflect.Slice {
		return errors.InternalErrorf("validateWorkflowFieldNames given a non-slice type")
	}
	items := make([]interface{}, s.Len())
	for i := 0; i < s.Len(); i++ {
		items[i] = s.Index(i).Interface()
	}
	names := make(map[string]bool)
	getNameFieldValue := func(val interface{}) (string, error) {
		s := reflect.ValueOf(val)
		for i := 0; i < s.NumField(); i++ {
			typeField := s.Type().Field(i)
			if typeField.Name == "Name" {
				return s.Field(i).String(), nil
			}
		}
		return "", errors.InternalError("No 'Name' field in struct")
	}

	for i, item := range items {
		name, err := getNameFieldValue(item)
		if err != nil {
			return err
		}
		if name == "" {
			return errors.Errorf(errors.CodeBadRequest, "[%d].name is required", i)
		}
		var errs []string
		t := reflect.TypeOf(item)
		if t == reflect.TypeOf(wfv1.Parameter{}) || t == reflect.TypeOf(wfv1.Artifact{}) {
			errs = isValidParamOrArtifactName(name)
		} else {
			errs = isValidWorkflowFieldName(name)
		}
		if len(errs) != 0 {
			return errors.Errorf(errors.CodeBadRequest, "[%d].name: '%s' is invalid: %s", i, name, strings.Join(errs, ";"))
		}
		_, ok := names[name]
		if ok {
			return errors.Errorf(errors.CodeBadRequest, "[%d].name '%s' is not unique", i, name)
		}
		names[name] = true
	}
	return nil
}
450207
func (r Layout_Item) GetLayoutItemType() (resp datatypes.Layout_Item_Type, err error) {
	err = r.Session.DoRequest("SoftLayer_Layout_Item", "getLayoutItemType", nil, &r.Options, &resp)
	return
}
1353054
func ParseSortWorkItemsBy(s *string) (SortWorkItemsBy, error) {
	if s == nil {
		// this is the default case
		// which returns workitems with highest execution order
		return SortWorkItemsByDefault, nil
	}

	var sort SortWorkItemsBy
	switch *s {
	case "execution":
		sort = SortWorkItemsByExecutionAsc
	case "-execution":
		sort = SortWorkItemsByExecutionDesc
	case "created":
		sort = SortWorkItemsByCreatedAtAsc
	case "-created":
		sort = SortWorkItemsByCreatedAtDesc
	case "updated":
		sort = SortWorkItemsByUpdatedAtAsc
	case "-updated":
		sort = SortWorkItemsByUpdatedAtDesc
	default:
		return SortWorkItemsBy(""), errors.NewBadParameterError("sort", *s)
	}
	return sort, nil
}
512435
func ConvertWorkItemLinkTypeFromModel(request *http.Request, modelLinkType link.WorkItemLinkType) app.WorkItemLinkTypeSingle {
	spaceTemplateRelatedURL := rest.AbsoluteURL(request, app.SpaceTemplateHref(modelLinkType.SpaceTemplateID.String()))
	spaceRelatedURL := rest.AbsoluteURL(request, app.SpaceHref(space.SystemSpace.String()))

	topologyStr := modelLinkType.Topology.String()
	var converted = app.WorkItemLinkTypeSingle{
		Data: &app.WorkItemLinkTypeData{
			Type: link.EndpointWorkItemLinkTypes,
			ID:   &modelLinkType.ID,
			Attributes: &app.WorkItemLinkTypeAttributes{
				Name:               &modelLinkType.Name,
				Description:        modelLinkType.Description,
				Version:            &modelLinkType.Version,
				CreatedAt:          &modelLinkType.CreatedAt,
				UpdatedAt:          &modelLinkType.UpdatedAt,
				ForwardName:        &modelLinkType.ForwardName,
				ForwardDescription: modelLinkType.ForwardDescription,
				ReverseName:        &modelLinkType.ReverseName,
				ReverseDescription: modelLinkType.ReverseDescription,
				Topology:           &topologyStr,
			},
			Relationships: &app.WorkItemLinkTypeRelationships{
				Space:         app.NewSpaceRelation(space.SystemSpace, spaceRelatedURL),
				SpaceTemplate: app.NewSpaceTemplateRelation(modelLinkType.SpaceTemplateID, spaceTemplateRelatedURL),
			},
		},
	}
	return converted
}