package plugin

/*
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

import (
	"strconv"
	"strings"
	"time"

	"github.com/apache/trafficcontrol/grove/web"

	"github.com/apache/trafficcontrol/lib/go-log"
)

const NSPerSec = 1000000000

func init() {
	AddPlugin(20000, Funcs{afterRespond: atsLog})
}

func atsLog(icfg interface{}, d AfterRespondData) {
	now := time.Now()
	bytesSent := web.TryGetBytesWritten(d.W, d.Conn, d.BytesWritten)

	proxyHierarchyStr, proxyNameStr := getParentStrings(d.RespCode, d.CacheHit, d.ProxyStr, d.ToFQDN)

	log.EventRaw(atsEventLogStr(
		now,
		d.ClientIP,
		d.Hostname,
		d.Req.Host,
		d.Port,
		d.ToFQDN,
		d.Scheme,
		d.Req.URL.String(),
		d.Req.Method,
		d.Req.Proto,
		d.RespCode,
		now.Sub(d.ReqTime),
		bytesSent,
		d.OriginCode,
		d.OriginBytes,
		d.RespSuccess,
		d.OriginReqSuccess,
		getCacheHitStr(d.CacheHit, d.OriginConnectFailed),
		proxyHierarchyStr,
		proxyNameStr,
		d.Req.UserAgent(),
		d.Req.Header.Get("X-Money-Trace"),
		d.RequestID,
	))
}

// getParentStrings returns the phr and pqsn ATS log event strings (in that order).
// This covers almost all occurences that we currently see from ATS.
func getParentStrings(code int, hit bool, proxyStr string, toFQDN string) (string, string) {
	// the most common case (hopefully), do this first
	if hit {
		return "NONE", "-"
	}
	if code >= 200 {
		if proxyStr != "" {
			return "PARENT_HIT", strings.Split(proxyStr, ":")[0]
		}
		return "DIRECT", toFQDN
	}
	return "EMPTY", "-"
}

// getCacheHitStr returns the event log string for whether the request was a cache hit. For a request not in the cache, pass `ReuseCannot` to indicate a cache miss.
func getCacheHitStr(hit bool, originConnectFailed bool) string {
	if originConnectFailed {
		return "ERR_CONNECT_FAIL"
	}
	if hit {
		return "TCP_HIT"
	}
	return "TCP_MISS"
}

func atsEventLogStr(
	timestamp time.Time, // (prefix)
	clientIP string, // chi
	selfHostname string,
	reqHost string, // phn
	reqPort string, // php
	originHost string, // shn
	scheme string, // url
	url string, // url
	method string, // cqhm
	protocol string, // cqhv
	respCode int, // pssc
	timeToServe time.Duration, // ttms
	bytesSent uint64, // b
	originStatus int, // sssc
	originBytes uint64, // sscl
	clientRespSuccess bool, // cfsc
	originReqSuccess bool, // pfsc
	cacheHit string, // crc
	proxyUsed string, // phr
	thisProxyName string, // pqsn
	clientUserAgent string, // client user agent
	xmt string, // moneytrace header
	requestID uint64, // Grove tracing ID - not part of real ATS log format
) string {
	unixNano := timestamp.UnixNano()
	unixSec := unixNano / NSPerSec
	unixFrac := (unixNano / (NSPerSec / 1000)) - (unixSec * 1000) // gives fractional seconds to three decimal points, like the ATS logs.
	unixFracStr := strconv.FormatInt(unixFrac, 10)
	for len(unixFracStr) < 3 {
		unixFracStr = "0" + unixFracStr // leading zeros, so e.g. a fraction of '42' becomes '1234.042' not '1234.42'
	}
	cfsc := "FIN"
	if !clientRespSuccess {
		cfsc = "INTR"
	}
	pfsc := "FIN"
	if !originReqSuccess {
		pfsc = "INTR"
	}

	// TODO escape quotes within useragent, moneytrace
	clientUserAgent = `"` + clientUserAgent + `"`
	if xmt == "" {
		xmt = `"-"`
	} else {
		xmt = `"` + xmt + `"`
	}

	// 	1505408269.011 chi=2001:beef:cafe:f::2 phn=cdn-ec-nyc-001-01.nyc.kabletown.net php=80 shn=disc-org.kabletown.net url=http://edge.disc.kabletown.net/250001/3306/lb.xml cqhm=GET cqhv=HTTP/1.1 pssc=200 ttms=0 b=1778 sssc=000 sscl=0 cfsc=FIN pfsc=FIN crc=TCP_MEM_HIT phr=NONE pqsn=- uas="Go-http-client/1.1" xmt="-"
	return strconv.FormatInt(unixSec, 10) + "." + unixFracStr + " chi=" + clientIP + " phn=" + selfHostname + " php=" + reqPort + " shn=" + originHost + " url=" + scheme + "://" + reqHost + url + " cqhn=" + method + " cqhv=" + protocol + " pssc=" + strconv.FormatInt(int64(respCode), 10) + " ttms=" + strconv.FormatInt(int64(timeToServe/time.Millisecond), 10) + " b=" + strconv.FormatInt(int64(bytesSent), 10) + " sssc=" + strconv.FormatInt(int64(originStatus), 10) + " sscl=" + strconv.FormatInt(int64(originBytes), 10) + " cfsc=" + cfsc + " pfsc=" + pfsc + " crc=" + cacheHit + " phr=" + proxyUsed + " pqsn=" + thisProxyName + " uas=" + clientUserAgent + " xmt=" + xmt + " reqid=" + strconv.FormatUint(requestID, 10) + "\n"
}
