package digitaltwin_test

import (
	"encoding/json"

	"github.com/fiskerinc/cloud-services/pkg/common"
	"github.com/fiskerinc/cloud-services/pkg/duration"
)

func clone(orig *common.JSONDigitalTwin) (*common.JSONDigitalTwin, error) {
	origJSON, err := json.Marshal(orig)
	if err != nil {
		return nil, err
	}

	clone := common.JSONDigitalTwin{}
	if err = json.Unmarshal(origJSON, &clone); err != nil {
		return nil, err
	}

	return &clone, nil
}

func cloneAndChangeOnline(orig *common.JSONDigitalTwin) (*common.JSONDigitalTwin, error) {
	cloned, err := clone(orig)
	if err != nil {
		return nil, err
	}
	cloned.Online = !cloned.Online
	return cloned, nil
}

func cloneAndChangeHMIOnline(orig *common.JSONDigitalTwin) (*common.JSONDigitalTwin, error) {
	cloned, err := clone(orig)
	if err != nil {
		return nil, err
	}
	cloned.OnlineHMI = !cloned.OnlineHMI
	return cloned, nil
}

func cloneAndChangeVehicleSpeed(orig *common.JSONDigitalTwin) (*common.JSONDigitalTwin, error) {
	cloned, err := clone(orig)
	if err != nil {
		return nil, err
	}
	cloned.VehicleSpeed.Speed = cloned.VehicleSpeed.Speed + 10.0
	return cloned, nil
}

func cloneAndChangeGear(orig *common.JSONDigitalTwin) (*common.JSONDigitalTwin, error) {
	cloned, err := clone(orig)
	if err != nil {
		return nil, err
	}
	cloned.Gear.InPark = !cloned.Gear.InPark
	return cloned, nil
}

func cloneAndChangeBattery(orig *common.JSONDigitalTwin) (*common.JSONDigitalTwin, error) {
	cloned, err := clone(orig)
	if err != nil {
		return nil, err
	}
	*cloned.Battery.Percent = *cloned.Battery.Percent - 10.0
	return cloned, nil
}

func cloneAndChangeDoor(orig *common.JSONDigitalTwin) (*common.JSONDigitalTwin, error) {
	cloned, err := clone(orig)
	if err != nil {
		return nil, err
	}
	cloned.Doors.LeftFront = !cloned.Doors.LeftFront
	return cloned, nil
}

func cloneAndChangeLocation(orig *common.JSONDigitalTwin) (*common.JSONDigitalTwin, error) {
	cloned, err := clone(orig)
	if err != nil {
		return nil, err
	}
	cloned.Location.Altitude = cloned.Location.Altitude + 100.0
	return cloned, nil
}

func cloneAndChangeLocks(orig *common.JSONDigitalTwin) (*common.JSONDigitalTwin, error) {
	cloned, err := clone(orig)
	if err != nil {
		return nil, err
	}
	cloned.Locks.Driver = !cloned.Locks.Driver
	return cloned, nil
}

func cloneAndChangeWindows(orig *common.JSONDigitalTwin) (*common.JSONDigitalTwin, error) {
	cloned, err := clone(orig)
	if err != nil {
		return nil, err
	}
	cloned.Windows.LeftFront = cloned.Windows.LeftFront + 1
	return cloned, nil
}

func cloneAndChangeClimateControl(orig *common.JSONDigitalTwin) (*common.JSONDigitalTwin, error) {
	cloned, err := clone(orig)
	if err != nil {
		return nil, err
	}
	cloned.ClimateControl.AmbientTemperature = cloned.ClimateControl.AmbientTemperature + 1
	return cloned, nil
}

func cloneAndChangeTrexVersion(orig *common.JSONDigitalTwin) (*common.JSONDigitalTwin, error) {
	cloned, err := clone(orig)
	if err != nil {
		return nil, err
	}
	cloned.TRexVersion = cloned.TRexVersion + "new_version"
	return cloned, nil
}

func cloneAndChangeIP(orig *common.JSONDigitalTwin) (*common.JSONDigitalTwin, error) {
	cloned, err := clone(orig)
	if err != nil {
		return nil, err
	}
	cloned.IP = "172.0.0.99"
	return cloned, nil
}

func cloneAndUpdateAt(orig *common.JSONDigitalTwin) (*common.JSONDigitalTwin, error) {
	cloned, err := clone(orig)
	if err != nil {
		return nil, err
	}
	*cloned.UpdatedAt = cloned.UpdatedAt.Add(-1 * duration.Minute)
	return cloned, nil
}
