package util

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"

	"github.com/ngaut/log"
	"github.com/pingcap/wormhole/ether/api"
	"github.com/pingcap/wormhole/pkg/whpb"
)

type DatasourceResponse struct {
	Message string          `json:"_index"`
	Code    int             `json:"code"`
	Data    *api.Datasource `json:"data"`
}

func CreateDatasource(etherUrl string, cfg *DBConfig) (*api.Datasource, error) {
	url := fmt.Sprintf("http://%s/ether/api/v1/datasources", etherUrl)
	db := &whpb.DBAccount{
		Host: cfg.Host,
		Port: int32(cfg.Port),
		Username: cfg.User,
		Password: cfg.Password,
	}
	datasource := &api.Datasource{
		ID:   1,
		Name: cfg.Name,
		Type: "mysql",
		DB:   *db,
		PartitionNum: 10,
	}

	data, err := json.Marshal(datasource)
	if err != nil {
		return nil, err
	}

	resp, err := sendRequest(url, data)
	if err != nil {
		return nil, err
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	ret := new(DatasourceResponse)
	err = json.Unmarshal(body, &ret)
	if err != nil {
		return nil, err
	}

	log.Infof("response Body: %s", string(body))
	return ret.Data, nil

}

func CreateDataTube(etherUrl string, sourceCfg *DBConfig, targetCfg *DBConfig, sourceInfo *api.Datasource, tables []string) error {
	url := fmt.Sprintf("http://%s/ether/api/v1/pipelines", etherUrl)

	target := &api.TargetDB {
		Name:  targetCfg.Name,
		Type:  "tidb",
		DB:     whpb.DBAccount {
			Host:     targetCfg.Host,
			Port:     int32(targetCfg.Port),
			Username: targetCfg.User,
			Password: targetCfg.Password,
		},

	}
	
	schema := &whpb.Schema {
		Name:   sourceCfg.Name,
		Tables: tables,
	}

	source := &api.SourceDB {
		Name:  sourceCfg.Name,
		Type:  "mysql",
		DB:     whpb.DBAccount {
			Host:     sourceCfg.Host,
			Port:     int32(sourceCfg.Port),
			Username: sourceCfg.User,
			Password: sourceCfg.Password,
		},
		Schemas: []*whpb.Schema{schema},
		WillSyncMore: false,
		NoLocks: false,
	}

	pipeline := &api.Pipeline {
		Target:  target,
		Sources: []*api.SourceDB{source},
		PartitionNum: 10,

	}

	data, err := json.Marshal(pipeline)
	if err != nil {
		return err
	}

	resp, err := sendRequest(url, data)
	if err != nil {
		return err
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	log.Infof("response Body: %s", string(body))

	return nil

}

func sendRequest(url string, data []byte) (*http.Response, error) {
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
	if err != nil {
		return nil, err
	}
	req.Header.Set("X-Custom-Header", "myvalue")
	req.Header.Set("Content-Type", "application/json")

	client := http.Client{}
	resp, err := client.Do(req)
	return resp, err
}
