package main

import (
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/yandex/pandora/cli"
	"github.com/yandex/pandora/core"
	"github.com/yandex/pandora/core/aggregator/netsample"
	coreimport "github.com/yandex/pandora/core/import"
	"github.com/yandex/pandora/core/register"
)

type Ammo struct {
	Tag        string
	URLPart    string
	HostHeader string
}

type GunConfig struct {
	Target string `validate:"required"`
	Global int
}

type Gun struct {
	client http.Client
	conf   GunConfig
	aggr   core.Aggregator
	core.GunDeps
}

func ExampleGun(conf GunConfig) *Gun {
	return &Gun{conf: conf}
}

func (g *Gun) Bind(aggr core.Aggregator, deps core.GunDeps) error {
	tr := &http.Transport{
		MaxIdleConns:       1,
		IdleConnTimeout:    time.Duration(g.conf.Global) * time.Second,
		DisableCompression: true,
	}
	g.client = http.Client{Transport: tr}
	g.aggr = aggr
	g.GunDeps = deps
	return nil
}

func (g *Gun) Shoot(ammo core.Ammo) {
	customAmmo := ammo.(*Ammo)
	g.shoot(customAmmo)
}

func (g *Gun) shoot(ammo *Ammo) {
	code := 0
	JobID := 2000000 + rand.Intn(580000)
	req, _ := http.NewRequest("GET", strings.Join([]string{"http://", g.conf.Target, ammo.Tag, strconv.Itoa(JobID), ammo.URLPart}, ""), nil)
	req.Header.Add("Connection", "keep-alive")
	req.Header.Add("Host", ammo.HostHeader)

	sample := netsample.Acquire(ammo.Tag)
	rs, err := g.client.Do(req)
	if err == nil {
		code = rs.StatusCode
		respBody, _ := ioutil.ReadAll(rs.Body)
		_ = rs.Body.Close()
		fmt.Println(string(respBody))
	} else {
		fmt.Println(err)
	}

	defer func() {
		sample.SetProtoCode(code)
		g.aggr.Report(sample)
	}()
}

func main() {
	fs := coreimport.GetFs()
	coreimport.Import(fs)
	coreimport.RegisterCustomJSONProvider("example_provider", func() core.Ammo { return &Ammo{} })
	register.Gun("example", ExampleGun, func() GunConfig {
		return GunConfig{
			Target: "default target",
		}
	})
	cli.Run()
}
