package types

import (
	"database/sql/driver"
	"encoding/json"
	"fmt"
	"reflect"
)

// Value implement driver.Valuer on Labels
func (labels Labels) Value() (driver.Value, error) {
	if len(labels) == 0 {
		return nil, nil
	}
	return json.Marshal(labels)
}

// Scan implement sql.Scanner on Labels
func (labels Labels) Scan(src interface{}) error {
	v := reflect.ValueOf(src)
	if !v.IsValid() || v.CanAddr() && v.IsNil() {
		return nil
	}
	switch ts := src.(type) {
	case []byte:
		return json.Unmarshal(ts, &labels)
	default:
		return fmt.Errorf("Could not not decode type %T -> %T", src, labels)
	}
}

// Value implement driver.Valuer on stringSlice
func (s stringSlice) Value() (driver.Value, error) {
	if len(s) == 0 {
		return nil, nil
	}
	return json.Marshal(s)
}

// Scan implement sql.Scanner on *stringSlice
func (s *stringSlice) Scan(src interface{}) error {
	v := reflect.ValueOf(src)
	if !v.IsValid() || v.CanAddr() && v.IsNil() {
		return nil
	}
	switch ts := src.(type) {
	case []byte:
		return json.Unmarshal(ts, &s)
	default:
		return fmt.Errorf("Could not not decode type %T -> %T", src, s)
	}
}

// Value implement driver.Valuer on Rules
func (rs Rules) Value() (driver.Value, error) {
	if len(rs) == 0 {
		return nil, nil
	}
	return json.Marshal(rs)
}

// Scan implement sql.Scanner on *Rules
func (rs *Rules) Scan(src interface{}) error {
	v := reflect.ValueOf(src)
	if !v.IsValid() || v.CanAddr() && v.IsNil() {
		return nil
	}
	switch ts := src.(type) {
	case []byte:
		return json.Unmarshal(ts, &rs)
	default:
		return fmt.Errorf("Could not not decode type %T -> %T", src, rs)
	}
}

// Value implement driver.Valuer on ResourceRequirements
func (r ResourceRequirements) Value() (driver.Value, error) {
	return json.Marshal(r)
}

// Scan implement sql.Scanner on ResourceRequirements
func (r *ResourceRequirements) Scan(src interface{}) error {
	v := reflect.ValueOf(src)
	if !v.IsValid() || v.CanAddr() && v.IsNil() {
		return nil
	}
	switch ts := src.(type) {
	case []byte:
		return json.Unmarshal(ts, &r)
	default:
		return fmt.Errorf("Could not not decode type %T -> %T", src, r)
	}
}

// Value implement driver.Valuer on TiDBClusterBackupSpec
func (r TiDBClusterBackupSpec) Value() (driver.Value, error) {
	return json.Marshal(r)
}

// Scan implement sql.Scanner on TiDBClusterBackupSpec
func (r *TiDBClusterBackupSpec) Scan(src interface{}) error {
	v := reflect.ValueOf(src)
	if !v.IsValid() || v.CanAddr() && v.IsNil() {
		return nil
	}
	switch ts := src.(type) {
	case []byte:
		return json.Unmarshal(ts, &r)
	default:
		return fmt.Errorf("Could not not decode type %T -> %T", src, r)
	}
}

// Value implement driver.Valuer on TiDBClusterBackupStatus
func (r TiDBClusterBackupStatus) Value() (driver.Value, error) {
	return json.Marshal(r)
}

// Scan implement sql.Scanner on TiDBClusterBackupStatus
func (r *TiDBClusterBackupStatus) Scan(src interface{}) error {
	v := reflect.ValueOf(src)
	if !v.IsValid() || v.CanAddr() && v.IsNil() {
		return nil
	}
	switch ts := src.(type) {
	case []byte:
		return json.Unmarshal(ts, &r)
	default:
		return fmt.Errorf("Could not not decode type %T -> %T", src, r)
	}
}

// Value implement driver.Valuer on ResourceRequirement
func (r ResourceRequirement) Value() (driver.Value, error) {
	return json.Marshal(r)
}

// Scan implement sql.Scanner on ResourceRequirement
func (r *ResourceRequirement) Scan(src interface{}) error {
	v := reflect.ValueOf(src)
	if !v.IsValid() || v.CanAddr() && v.IsNil() {
		return nil
	}
	switch ts := src.(type) {
	case []byte:
		return json.Unmarshal(ts, &r)
	default:
		return fmt.Errorf("Could not not decode type %T -> %T", src, r)
	}
}

// Value implement driver.Valuer on EnvVars
func (r EnvVars) Value() (driver.Value, error) {
	return json.Marshal(r)
}

// Scan implement sql.Scanner on EnvVars
func (r *EnvVars) Scan(src interface{}) error {
	v := reflect.ValueOf(src)
	if !v.IsValid() || v.CanAddr() && v.IsNil() {
		return nil
	}
	switch ts := src.(type) {
	case []byte:
		return json.Unmarshal(ts, &r)
	default:
		return fmt.Errorf("Could not not decode type %T -> %T", src, r)
	}
}

// Value implement driver.Valuer on Actions
func (r Actions) Value() (driver.Value, error) {
	return json.Marshal(r)
}

// Scan implement sql.Scanner on Actions
func (r *Actions) Scan(src interface{}) error {
	v := reflect.ValueOf(src)
	if !v.IsValid() || v.CanAddr() && v.IsNil() {
		return nil
	}
	switch ts := src.(type) {
	case []byte:
		return json.Unmarshal(ts, &r)
	default:
		return fmt.Errorf("Could not not decode type %T -> %T", src, r)
	}
}

// Value implement driver.Valuer on TestReport
func (r TestReport) Value() (driver.Value, error) {
	return json.Marshal(r)
}

// Scan implement sql.Scanner on TestReport
func (r *TestReport) Scan(src interface{}) error {
	v := reflect.ValueOf(src)
	if !v.IsValid() || v.CanAddr() && v.IsNil() {
		return nil
	}
	switch ts := src.(type) {
	case []byte:
		return json.Unmarshal(ts, &r)
	default:
		return fmt.Errorf("Could not not decode type %T -> %T", src, r)
	}
}

// Value implement driver.Valuer on Cat
func (r Cat) Value() (driver.Value, error) {
	return json.Marshal(r)
}

// Scan implement sql.Scanner on Cat
func (r *Cat) Scan(src interface{}) error {
	v := reflect.ValueOf(src)
	if !v.IsValid() || v.CanAddr() && v.IsNil() {
		return nil
	}
	switch ts := src.(type) {
	case []byte:
		return json.Unmarshal(ts, &r)
	default:
		return fmt.Errorf("Could not not decode type %T -> %T", src, r)
	}
}

// Value implement driver.Valuer on TestConfigs
func (r TestConfigs) Value() (driver.Value, error) {
	return json.Marshal(r)
}

// Scan implement sql.Scanner on TestConfigs
func (r *TestConfigs) Scan(src interface{}) error {
	v := reflect.ValueOf(src)
	if !v.IsValid() || v.CanAddr() && v.IsNil() {
		return nil
	}
	switch ts := src.(type) {
	case []byte:
		return json.Unmarshal(ts, &r)
	default:
		return fmt.Errorf("Could not not decode type %T -> %T", src, r)
	}
}
