<commit_before>package ovsdb

import (
	"reflect"

	uuid "github.com/satori/go.uuid"
	ovs "github.com/socketplane/libovsdb"
)

// NewFakeOvsdbClient returns an ovsdb client with mocked ovsdb.
func NewFakeOvsdbClient() Client {
	// Clears uuidMap for new test.
	uuidMap = map[string]string{}

	return Client{fakeOvsdbClient{
		databases: map[string]fakeDb{},
	}}
}

// Default OFPort used during creation of interface.
const defaultOFPort float64 = 123

type fakeOvsdbClient struct {
	databases map[string]fakeDb
}

type fakeDb struct {
	tables map[string]fakeTable
}

type fakeTable struct {
	rows map[string]fakeRow
}

type fakeRow map[string]interface{}

// Mapping of UUIDName:UUID.
var uuidMap map[string]string

type fakeCondition struct {
	column, function, value string
}

func (cond fakeCondition) matches(row fakeRow) bool {
	toMatch := ""

	switch v := row[cond.column].(type) {
	case string:
		toMatch = v
	case []interface{}:
		if cond.column == "_uuid" {
			toMatch = v[1].(string)
		} else {
			panic("condition on this column is not yet supported: " +
				cond.column)
		}
	default:
		panic("condition type is not yet supported:" +
			reflect.TypeOf(row[cond.column]).String())
	}

	switch cond.function {
	case "==":
		return toMatch == cond.value
	case "!=":
		return toMatch != cond.value
	default:
		panic("condition func is not yet supported: " + cond.function)
	}
}

type fakeMutation struct {
	column  string
	mutator string
	value   interface{}
}

// Applies mutation on a row, and returns number of mutations applied.
func (mutation fakeMutation) apply(row *fakeRow) int {
	mutationCount := 0
	column := (*row)[mutation.column].([]interface{})

	switch mutationVal := mutation.value.(type) {
	case *ovs.OvsSet:
		data := column[1].([]interface{})

		uuidGeneric := mutationVal.GoSet[0].(ovs.UUID).GoUUID
		uuid, ok := uuidMap[uuidGeneric]
		if !ok {
			uuid = uuidGeneric
		}
		switch mutation.mutator {
		case "insert":
			data = append(data, []interface{}{"uuid", uuid})
			mutationCount++
		case "delete":
			for i, e := range data {
				if e.([]interface{})[1] == uuid {
					data = append(data[:i], data[i+1:]...)
				}
			}
			mutationCount++
		default:
			panic("mutator is not yet supported:" + mutation.mutator)
		}
		column[1] = data
	case *ovs.OvsMap:
		switch data := column[1].(type) {
		case map[string]interface{}:
			for k, v := range mutationVal.GoMap {
				switch mutation.mutator {
				case "insert":
					data[k.(string)] = v
					mutationCount++
				default:
					panic("mutator is not yet supported:" +
						mutation.mutator)
				}
			}
			column[1] = data
		case []interface{}:
			for k, v := range mutationVal.GoMap {
				switch mutation.mutator {
				case "insert":
					data = append(data, []interface{}{k, v})
					mutationCount++
				default:
					panic("mutator is not yet supported:" +
						mutation.mutator)
				}
			}
			column[1] = data
		default:
			panic("not yet supported.")
		}
	default:
		panic("mutation type is not yet supported:" +
			reflect.TypeOf(mutationVal).String())
	}<commit_msg>ovsdb: Break up ovsdb mock apply method<commit_after>package ovsdb

import (
	"reflect"

	uuid "github.com/satori/go.uuid"
	ovs "github.com/socketplane/libovsdb"
)

// NewFakeOvsdbClient returns an ovsdb client with mocked ovsdb.
func NewFakeOvsdbClient() Client {
	// Clears uuidMap for new test.
	uuidMap = map[string]string{}

	return Client{fakeOvsdbClient{
		databases: map[string]fakeDb{},
	}}
}

// Default OFPort used during creation of interface.
const defaultOFPort float64 = 123

type fakeOvsdbClient struct {
	databases map[string]fakeDb
}

type fakeDb struct {
	tables map[string]fakeTable
}

type fakeTable struct {
	rows map[string]fakeRow
}

type fakeRow map[string]interface{}

// Mapping of UUIDName:UUID.
var uuidMap map[string]string

type fakeCondition struct {
	column, function, value string
}

func (cond fakeCondition) matches(row fakeRow) bool {
	toMatch := ""

	switch v := row[cond.column].(type) {
	case string:
		toMatch = v
	case []interface{}:
		if cond.column == "_uuid" {
			toMatch = v[1].(string)
		} else {
			panic("condition on this column is not yet supported: " +
				cond.column)
		}
	default:
		panic("condition type is not yet supported:" +
			reflect.TypeOf(row[cond.column]).String())
	}

	switch cond.function {
	case "==":
		return toMatch == cond.value
	case "!=":
		return toMatch != cond.value
	default:
		panic("condition func is not yet supported: " + cond.function)
	}
}

type fakeMutation struct {
	column  string
	mutator string
	value   interface{}
}

// Applies mutation on a row, and returns number of mutations applied.
func (mutation fakeMutation) apply(row *fakeRow) int {
	switch mutationVal := mutation.value.(type) {
	case *ovs.OvsSet:
		return mutation.applySet(row, mutationVal)
	case *ovs.OvsMap:
		return mutation.applyMap(row, mutationVal)
	default:
		panic("mutation type is not yet supported:" +
			reflect.TypeOf(mutationVal).String())
	}
}

func (mutation fakeMutation) applySet(row *fakeRow, set *ovs.OvsSet) int {
	mutationCount := 0
	column := (*row)[mutation.column].([]interface{})
	data := column[1].([]interface{})

	uuidGeneric := set.GoSet[0].(ovs.UUID).GoUUID
	uuid, ok := uuidMap[uuidGeneric]
	if !ok {
		uuid = uuidGeneric
	}
	switch mutation.mutator {
	case "insert":
		data = append(data, []interface{}{"uuid", uuid})
		mutationCount++
	case "delete":
		for i, e := range data {
			if e.([]interface{})[1] == uuid {
				data = append(data[:i], data[i+1:]...)
				break
			}
		}
		mutationCount++
	default:
		panic("mutator is not yet supported:" + mutation.mutator)
	}

	column[1] = data
	(*row)[mutation.column] = column
	return mutationCount
}

func (mutation fakeMutation) applyMap(row *fakeRow, mp *ovs.OvsMap) int {
	mutationCount := 0
	column := (*row)[mutation.column].([]interface{})

	switch data := column[1].(type) {
	case map[string]interface{}:
		for k, v := range mp.GoMap {
			switch mutation.mutator {
			case "insert":
				data[k.(string)] = v
				mutationCount++
			default:
				panic("mutator is not yet supported:" +
					mutation.mutator)
			}
		}
		column[1] = data
	case []interface{}:
		for k, v := range mp.GoMap {
			switch mutation.mutator {
			case "insert":
				data = append(data, []interface{}{k, v})
				mutationCount++
			default:
				panic("mutator is not yet supported:" +
					mutation.mutator)
			}
		}
		column[1] = data
	default:
		panic("not yet supported.")
	}
{'fraction_non_alphanumeric': 0.1367163252638113, 'fraction_numerical': 0.004810676598386096, 'mean_word_length': 3.718155197657394, 'pattern_counts': {'":': 12, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '486858', 'n_tokens_mistral': 2455, 'n_tokens_neox': 2203, 'n_words': 581}