<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"net/http"
	"os"

	"github.com/lxc/lxd"
)

type resp struct {
	Type     string      `json:"type"`
	Result   string      `json:"result"`
	Metadata interface{} `json:"metadata"`
}

type Response interface {
	Render(w http.ResponseWriter) error
}

type syncResponse struct {
	success  bool
	metadata interface{}
}

func (r *syncResponse) Render(w http.ResponseWriter) error {
	result := "success"
	if !r.success {
		result = "failure"
	}

	resp := resp{Type: string(lxd.Sync), Result: result, Metadata: r.metadata}
	enc, err := json.Marshal(&resp)
	if err != nil {
		return err
	}
	lxd.Debugf(string(enc))

	_, err = w.Write(enc)
	return err
}

/*
 * This function and AsyncResponse are simply wrappers for the response so
 * users don't have to remember whether to use {}s or ()s when building
 * responses.
 */
func SyncResponse(success bool, metadata interface{}) Response {
	return &syncResponse{success, metadata}
}

var EmptySyncResponse = &syncResponse{true, make(map[string]interface{})}

type asyncResponse struct {
	run    func() error
	cancel func() error
	ws     lxd.OperationSocket
}

func (r *asyncResponse) Render(w http.ResponseWriter) error {
	op, err := CreateOperation(nil, r.run, r.cancel, r.ws)
	if err != nil {
		return err
	}

	err = StartOperation(op)
	if err != nil {
		return err
	}

	body := lxd.Jmap{"type": lxd.Async, "operation": op}
	if r.ws != nil {
		body["metadata"] = lxd.Jmap{"websocket_secret": r.ws.Secret()}
	}

	return json.NewEncoder(w).Encode(body)
}

func AsyncResponse(run func() error, cancel func() error) Response {
	return AsyncResponseWithWs(run, cancel, nil)
}

func AsyncResponseWithWs(run func() error, cancel func() error, ws lxd.OperationSocket) Response {
	return &asyncResponse{run, cancel, ws}
}

type ErrorResponse struct {
	code int
	msg  string
}

func (r *ErrorResponse) Render(w http.ResponseWriter) error {
	buf := bytes.Buffer{}
	err := json.NewEncoder(&buf).Encode(lxd.Jmap{"type": lxd.Error, "error": r.msg, "error_code": r.code})

	if err != nil {
		return err
	}

	http.Error(w, buf.String(), r.code)
	return nil
}

/* Some standard responses */
var NotImplemented = &ErrorResponse{501, "not implemented"}
var NotFound = &ErrorResponse{404, "not found"}
var Forbidden = &ErrorResponse{403, "not authorized"}

func BadRequest(err error) Response {
	return &ErrorResponse{400, err.Error()}
}

func InternalError(err error) Response {
	return &ErrorResponse{500, err.Error()}
}

/*
 * Write the right error message based on err.
 */
func SmartError(err error) Response {
	switch err {<commit_msg>Use http status code constants instead of hardcoding<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"net/http"
	"os"

	"github.com/lxc/lxd"
)

type resp struct {
	Type     string      `json:"type"`
	Result   string      `json:"result"`
	Metadata interface{} `json:"metadata"`
}

type Response interface {
	Render(w http.ResponseWriter) error
}

type syncResponse struct {
	success  bool
	metadata interface{}
}

func (r *syncResponse) Render(w http.ResponseWriter) error {
	result := "success"
	if !r.success {
		result = "failure"
	}

	resp := resp{Type: string(lxd.Sync), Result: result, Metadata: r.metadata}
	enc, err := json.Marshal(&resp)
	if err != nil {
		return err
	}
	lxd.Debugf(string(enc))

	_, err = w.Write(enc)
	return err
}

/*
 * This function and AsyncResponse are simply wrappers for the response so
 * users don't have to remember whether to use {}s or ()s when building
 * responses.
 */
func SyncResponse(success bool, metadata interface{}) Response {
	return &syncResponse{success, metadata}
}

var EmptySyncResponse = &syncResponse{true, make(map[string]interface{})}

type asyncResponse struct {
	run    func() error
	cancel func() error
	ws     lxd.OperationSocket
}

func (r *asyncResponse) Render(w http.ResponseWriter) error {
	op, err := CreateOperation(nil, r.run, r.cancel, r.ws)
	if err != nil {
		return err
	}

	err = StartOperation(op)
	if err != nil {
		return err
	}

	body := lxd.Jmap{"type": lxd.Async, "operation": op}
	if r.ws != nil {
		body["metadata"] = lxd.Jmap{"websocket_secret": r.ws.Secret()}
	}

	return json.NewEncoder(w).Encode(body)
}

func AsyncResponse(run func() error, cancel func() error) Response {
	return AsyncResponseWithWs(run, cancel, nil)
}

func AsyncResponseWithWs(run func() error, cancel func() error, ws lxd.OperationSocket) Response {
	return &asyncResponse{run, cancel, ws}
}

type ErrorResponse struct {
	code int
	msg  string
}

func (r *ErrorResponse) Render(w http.ResponseWriter) error {
	buf := bytes.Buffer{}
	err := json.NewEncoder(&buf).Encode(lxd.Jmap{"type": lxd.Error, "error": r.msg, "error_code": r.code})

	if err != nil {
		return err
	}

	http.Error(w, buf.String(), r.code)
	return nil
}

/* Some standard responses */
var NotImplemented = &ErrorResponse{http.StatusNotImplemented, "not implemented"}
var NotFound = &ErrorResponse{http.StatusNotFound, "not found"}
var Forbidden = &ErrorResponse{http.StatusForbidden, "not authorized"}

func BadRequest(err error) Response {
	return &ErrorResponse{http.StatusBadRequest, err.Error()}
}

func InternalError(err error) Response {
	return &ErrorResponse{http.StatusInternalServerError, err.Error()}
}

/*
 * Write the right error message based on err.
 */
func SmartError(err error) Response {
	switch err {
{'fraction_non_alphanumeric': 0.1316620241411328, 'fraction_numerical': 0.002785515320334262, 'mean_word_length': 4.413065326633165, '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': '7171540', 'n_tokens_mistral': 1815, 'n_tokens_neox': 1776, 'n_words': 517}