package orm

import (
	"PPOSUtils/utils"
	"reflect"
)

//newMode ...
func newMode(database *DataBase, tableMode interface{}, injectionMp ...utils.Mp) *Mode {
	_mode := &Mode{
		database:  database,
		tableMode: tableMode,
	}
	_mode.injectionMp = database.injectionMp.Copy()
	//自定义值覆盖默认的隔离字段值
	if len(injectionMp) > 0 {
		for _k, _v := range injectionMp[0] {
			_mode.injectionMp.Set(_k, _v)
		}
	}
	return _mode
}

//Mode ...
type Mode struct {
	injectionMp utils.Mp    `xorm:"-"` //注入的字段
	tableMode   interface{} `xorm:"-"` //
	database    *DataBase   `xorm:"-"` //
}

//ResetInjectionMp 清空或重置隔离字段
func (that *Mode) ResetInjectionMp(injectionMp ...utils.Mp) {
	if len(injectionMp) == 0 {
		that.injectionMp = nil
	}
	if len(injectionMp) > 0 {
		that.injectionMp = injectionMp[0]
	}
}

func (that *Mode) DeletejectionMp(key string) {
	if that.injectionMp != nil {
		if _, _ok := that.injectionMp[key]; _ok {
			delete(that.injectionMp, key)
		}
	}
}

//
func (that *Mode) Add() error {
	_session := that.NewSession()
	defer _session.Close()
	if _, _err := _session.Insert(that.tableMode); _err != nil {
		return _err
	}
	return nil
}

//
func (that *Mode) AddMeeting(cols ...string) error {
	_session := that.NewSession()
	defer _session.Close()
	if _, _err := _session.AddMeeting(that.tableMode, cols...); _err != nil {
		return _err
	}
	return nil
}

func (that *Mode) Get() utils.Mp {
	_result := utils.NewMP()
	v := reflect.ValueOf(that.tableMode)
	if !v.IsNil() {
		t := reflect.TypeOf(that.tableMode)
		fieldNum := t.Elem().NumField()
		for i := 0; i < fieldNum; i++ {
			_name := t.Elem().Field(i).Name
			if t.Elem().Field(i).Tag.Get("json") != "" {
				_result.Set(t.Elem().Field(i).Tag.Get("json"), v.Elem().FieldByName(_name).Interface())
			}
		}
	}
	return _result
}

func (that *Mode) NewSession() *Session {
	//拿到克隆的session
	_session := that.database.newSession()
	//初始化克隆后sesion的注入字段与数据表模型
	if that.tableMode != nil {
		_session.Init(that.tableMode, that.injectionMp)
	}
	return _session
}

//Session ...
func (that *Mode) Session() *Session {
	return that.NewSession()
}

func (that *Mode) Begin() error {
	return that.database.Begin()
}

func (that *Mode) Rollback() error {
	return that.database.Rollback()
}

func (that *Mode) Commit() error {
	return that.database.Commit()
}
