package storage

import (
	"strings"
	"time"

	"github.com/juju/errors"
	"github.com/pingcap/schrodinger/pkg/types"
	"github.com/pingcap/schrodinger/util"
)

/* ---------------- mysql storage ------------------*/

func (m *mysqlClient) createObject(object *types.Object) error {
	t := time.Now().Format(util.TimeFormat)
	object.Ctime, object.Utime = t, t

	result, err := m.db.NamedExec(objectInsert, object)
	if err != nil {
		return errors.Trace(err)
	}

	object.ID, err = result.LastInsertId()
	if err != nil {
		return errors.Trace(err)
	}
	return nil
}

func (m *mysqlClient) updateObject(object *types.Object) error {
	t := time.Now().Format(util.TimeFormat)
	object.Utime = t

	if _, err := m.db.NamedExec(objectUpdate, object); err != nil {
		return errors.Trace(err)
	}
	return nil
}

func (m *mysqlClient) listObject() ([]*types.Object, error) {
	var objects []*types.Object

	rows, err := m.db.Queryx(objectSelect)
	if err != nil {
		return nil, errors.Trace(err)
	}

	for rows.Next() {
		var object types.Object
		if err := rows.StructScan(&object); err != nil {
			return nil, errors.Trace(err)
		}
		objects = append(objects, &object)
	}
	return objects, nil
}

func (m *mysqlClient) findObjectByID(ID int64) (*types.Object, error) {
	var object types.Object
	if err := m.db.Get(&object, objectSelectByID, ID); err != nil {
		if strings.Contains(err.Error(), "no rows in result set") {
			return nil, errors.NotFoundf("object %d", ID)
		}
		return nil, errors.Trace(err)
	}
	return &object, nil
}

const objectInsert = `
INSERT INTO object (
 experiment_id
,box_id
,name
,payload
,create_time
,update_time
) VALUES (
 :experiment_id
,:box_id
,:name
,:payload
,:create_time
,:update_time
)
`

const objectUpdate = `
UPDATE object SET
 experiment_id = :experiment_id
,box_id = :box_id
,name = :name
,payload = :payload
,update_time = :update_time
WHERE id = :id
`

const objectSelect = `
SELECT
 id
,experiment_id
,box_id
,name
,payload
,create_time
,update_time
FROM object
`

const objectSelectByID = `
SELECT
 id
,experiment_id
,box_id
,name
,payload
,create_time
,update_time
FROM object
WHERE id = ?
`
