package model

import (
	"context"
	"fmt"
	"time"

	"github.com/ClickHouse/clickhouse-go/v2"
)

//TODO JA3

type HttpSession struct {
	ID        string            `ch_name:"id" ch_type:"String"`
	SrcIP     string            `ch_name:"src_ip" ch_type:"String"` //TODO IPV6
	SrcPort   int               `ch_name:"src_port" ch_type:"UInt16"`
	DstIP     string            `ch_name:"dst_ip" ch_type:"String"` //TODO IPV6
	DstPort   int               `ch_name:"dst_port" ch_type:"UInt16"`
	NodeName  string            `ch_name:"node_name" ch_type:"String"`
	IsIpV6    bool              `ch_name:"is_ipv6" ch_type:"UInt8"`
	IsTls     bool              `ch_name:"is_tls" ch_type:"UInt8"`
	IsGmTls   bool              `ch_name:"is_gm_tls" ch_type:"UInt8"`
	IsHttp    bool              `ch_name:"is_http" ch_type:"UInt8"`
	IsHandled bool              `ch_name:"is_handled" ch_type:"UInt8"`
	SessionID string            `ch_name:"session_id" ch_type:"String"`
	Header    map[string]string `ch_name:"header" ch_type:"Map(String, String)"`
	UriParam  map[string]string `ch_name:"uri_param" ch_type:"Map(String, String)"`
	BodyParam map[string]string `ch_name:"body_param" ch_type:"Map(String, String)"`
	Method    string            `ch_name:"method" ch_type:"String"`
	Path      string            `ch_name:"path" ch_type:"String"`
	UA        string            `ch_name:"user_agent" ch_type:"String"`
	Host      string            `ch_name:"host" ch_type:"String"`
	RawHeader string            `ch_name:"raw_header" ch_type:"String"`
	Body      string            `ch_name:"body" ch_type:"String"`
	Data      string            `ch_name:"data" ch_type:"String"`
	StartTime time.Time         `ch_name:"start_time" ch_type:"DateTime('UTC')" ch_order:"true"`
	EndTime   time.Time         `ch_name:"end_time" ch_type:"DateTime('UTC')"`
	Service   string            `ch_name:"service" ch_type:"String"`
	//经过的时间 ms
	Duration int `ch_name:"duration" ch_type:"UInt32"`
	/* ip info */
	IsoCode     string `ch_name:"iso_code" ch_type:"String"`
	CountryName string `ch_name:"country_name" ch_type:"String"`
	CityName    string `ch_name:"city_name" ch_type:"String"`
	GeoHash     string `ch_name:"geo_hash" ch_type:"FixedString(12)"`
	AsnNumber   uint   `ch_name:"asn_number" ch_type:"UInt32"`
	AsnOrg      string `ch_name:"asn_org" ch_type:"String"`
	/* hash */
	BodyHash   string `ch_name:"body_hash" ch_type:"String"`
	HeaderHash string `ch_name:"header_hash" ch_type:"String"`
	PathHash   string `ch_name:"path_hash" ch_type:"String"`
	DataHash   string `ch_name:"data_hash" ch_type:"String"`
}

// Code generated by gen_clickhouse.go DO NOT EDIT.

func CreateTablehttp_session() string {
	query := `CREATE TABLE IF NOT EXISTS http_session (
	id String,
	src_ip String,
	src_port UInt16,
	dst_ip String,
	dst_port UInt16,
	node_name String,
	is_ipv6 UInt8,
	is_tls UInt8,
	is_gm_tls UInt8,
	is_http UInt8,
	is_handled UInt8,
	session_id String,
	header Map(String, String),
	uri_param Map(String, String),
	body_param Map(String, String),
	method String,
	path String,
	user_agent String,
	host String,
	raw_header String,
	body String,
	data String,
	start_time DateTime('UTC'),
	end_time DateTime('UTC'),
	service String,
	duration UInt32,
	iso_code String,
	country_name String,
	city_name String,
	geo_hash FixedString(12),
	asn_number UInt32,
	asn_org String,
	body_hash String,
	header_hash String,
	path_hash String,
	data_hash String
) ENGINE = MergeTree() ORDER BY start_time`

	return query
}

func InsertHttpSession(conn clickhouse.Conn, HttpSessions []HttpSession) error {
	batch, err := conn.PrepareBatch(context.Background(), "INSERT INTO http_session (id, src_ip, src_port, dst_ip, dst_port, node_name, is_ipv6, is_tls, is_gm_tls, is_http, is_handled, session_id, header, uri_param, body_param, method, path, user_agent, host, raw_header, body, data, start_time, end_time, service, duration, iso_code, country_name, city_name, geo_hash, asn_number, asn_org, body_hash, header_hash, path_hash, data_hash)")
	if err != nil {
		return fmt.Errorf("failed to prepare batch: %w", err)
	}

	for _, httpsession := range HttpSessions {
		if err := batch.Append(httpsession.ID, httpsession.SrcIP, httpsession.SrcPort, httpsession.DstIP, httpsession.DstPort, httpsession.NodeName, httpsession.IsIpV6, httpsession.IsTls, httpsession.IsGmTls, httpsession.IsHttp, httpsession.IsHandled, httpsession.SessionID, httpsession.Header, httpsession.UriParam, httpsession.BodyParam, httpsession.Method, httpsession.Path, httpsession.UA, httpsession.Host, httpsession.RawHeader, httpsession.Body, httpsession.Data, httpsession.StartTime, httpsession.EndTime, httpsession.Service, httpsession.Duration, httpsession.IsoCode, httpsession.CountryName, httpsession.CityName, httpsession.GeoHash, httpsession.AsnNumber, httpsession.AsnOrg, httpsession.BodyHash, httpsession.HeaderHash, httpsession.PathHash, httpsession.DataHash); err != nil {
			return fmt.Errorf("failed to append data: %w", err)
		}
	}

	if err := batch.Send(); err != nil {
		return fmt.Errorf("failed to send batch: %w", err)
	}
	return nil
}

// End of generated code
