package main

import (
	"code.justin.tv/dta/necronomicon-user-api/app"
	"database/sql"
	"github.com/goadesign/goa"
	"time"
)

// SnapshotController implements the snapshot resource.
type SnapshotController struct {
	*goa.Controller
	resources *Resources
}

// NewSnapshotController creates a snapshot controller.
func NewSnapshotController(service *goa.Service) *SnapshotController {
	return &SnapshotController{
		Controller: service.NewController("SnapshotController"),
	}
}

// Create runs the create action.
func (c *SnapshotController) Create(ctx *app.CreateSnapshotContext) error {
	// SnapshotController_Create: start_implement
	resources := c.resources
	db := resources.db
	payload := ctx.Payload
	changes := app.TwitchDtaNecronomiconUserapiSnapshotChangeCollection{}
	user, err := getUserFromBasicAuthString(ctx.RequestData)
	if err != nil {
		return err
	}
	for _, env := range payload.Environments {
		changes = append(
			changes,
			&app.TwitchDtaNecronomiconUserapiSnapshotChange{
				Name:      env.Name,
				Operation: env.Operation,
				Parent:    env.Parent,
				Values:    env.Values})
	}
	snapshot := &SnapshotModel{
		User:      user,
		Message:   payload.Message,
		Timestamp: time.Now(),
		Payload:   changes,
	}
	id, err := db.CreateSnapshot(snapshot)
	if err != nil {
		return err
	}
	ctx.ResponseData.Header().Set("Location", app.SnapshotHref(id))
	// SnapshotController_Create: end_implement
	return ctx.Created()
}

// List runs the list action.
func (c *SnapshotController) List(ctx *app.ListSnapshotContext) error {
	resources := c.resources
	db := resources.db
	res := app.SnapshotMediaListedCollection{}
	snapshots, err := db.GetSnapshots(ctx.From, ctx.To, ctx.Limit)
	if err != nil {
		return err
	}
	for _, snapshot := range snapshots {
		res = append(res, &app.SnapshotMediaListed{
			Message:    snapshot.Message,
			SnapshotID: snapshot.ID,
			Timestamp:  snapshot.Timestamp,
			User:       snapshot.User,
		})
	}
	return ctx.OKListed(res)
}

// Show runs the show action.
func (c *SnapshotController) Show(ctx *app.ShowSnapshotContext) error {
	resources := c.resources
	db := resources.db
	s, err := db.GetSnapshot(ctx.SnapshotID)
	if err == sql.ErrNoRows {
		return ctx.NotFound()
	}
	if err != nil {
		return err
	}

	res := app.SnapshotMedia{
		Message:   s.Message,
		Timestamp: s.Timestamp,
		User:      s.User,
		Changes:   s.Payload,
	}
	return ctx.OK(&res)
}
