package schema

import (
	"bytes"
	"encoding/json"
	"errors"
	"net/http"
	"strconv"
)

type remoteResponse struct {
	Code    int             `json:"errno"`
	Message string          `json:"errmsg"`
	Result  json.RawMessage `json:"result"`
}

type RemoteDriver struct {
	Url string `json:"url"`
}

func (driver *RemoteDriver) SaveColumn(schema *Schema) (err error) {
	var (
		buf []byte
		req *http.Request
		res *http.Response
	)
	if buf, err = json.Marshal(schema); err != nil {
		return
	}
	if req, err = http.NewRequest("POST", driver.Url, bytes.NewReader(buf)); err != nil {
		return
	}
	req.Header.Set("Content-Type", "application/json")
	if res, err = http.DefaultClient.Do(req); err != nil {
		return
	}
	defer func() {
		_ = res.Body.Close()
	}()
	resp := &remoteResponse{}
	if err = json.NewDecoder(res.Body).Decode(resp); err == nil {
		if resp.Code != 0 {
			err = errors.New(resp.Message)
		}
	}
	return
}

func (driver *RemoteDriver) DeleteColumn(id int) (err error) {
	var (
		req *http.Request
		res *http.Response
	)
	if req, err = http.NewRequest("DELETE", driver.Url+"/"+strconv.Itoa(id), nil); err != nil {
		return
	}
	if res, err = http.DefaultClient.Do(req); err != nil {
		return
	}
	defer func() {
		_ = res.Body.Close()
	}()
	resp := &remoteResponse{}
	if err = json.NewDecoder(res.Body).Decode(resp); err == nil {
		if resp.Code != 0 {
			err = errors.New(resp.Message)
		}
	}
	return
}

func (driver *RemoteDriver) Columns(module, table string) []*Schema {
	var (
		err error
		req *http.Request
		res *http.Response
	)
	values := make([]*Schema, 0)
	if req, err = http.NewRequest("GET", driver.Url+"/"+module+"/"+table, nil); err != nil {
		return values
	}
	if res, err = http.DefaultClient.Do(req); err != nil {
		return values
	}
	defer func() {
		_ = res.Body.Close()
	}()
	resp := &remoteResponse{}
	if err = json.NewDecoder(res.Body).Decode(resp); err == nil {
		if resp.Code != 0 {
			err = errors.New(resp.Message)
		} else {
			err = json.Unmarshal(resp.Result, &values)
		}
	}
	return values
}
