text: // Copyright 2020 New Relic Corporation. All rights reserved.
  // SPDX-License-Identifier: Apache-2.0
  
  package nrlambda
  
  import (
  	"net/http"
  	"net/url"
  	"strings"
  
  	"github.com/aws/aws-lambda-go/events"
  	newrelic "github.com/newrelic/go-agent"
  )
  
  func getEventSourceARN(event interface{}) string {
  	switch v := event.(type) {
  	case events.KinesisFirehoseEvent:
  		return v.DeliveryStreamArn
  	case events.KinesisEvent:
  		if len(v.Records) > 0 {
  			return v.Records[0].EventSourceArn
  		}
  	case events.CodeCommitEvent:
  		if len(v.Records) > 0 {
  			return v.Records[0].EventSourceARN
  		}
  	case events.DynamoDBEvent:
  		if len(v.Records) > 0 {
  			return v.Records[0].EventSourceArn
  		}
  	case events.SQSEvent:
  		if len(v.Records) > 0 {
  			return v.Records[0].EventSourceARN
  		}
  	case events.S3Event:
  		if len(v.Records) > 0 {
  			return v.Records[0].S3.Bucket.Arn
  		}
  	case events.SNSEvent:
  		if len(v.Records) > 0 {
  			return v.Records[0].EventSubscriptionArn
  		}
  	}
  	return ""
  }
  
  type webRequest struct {
  	header    http.Header
  	method    string
  	u         *url.URL
  	transport newrelic.TransportType
  }
  
  func (r webRequest) Header() http.Header               { return r.header }
  func (r webRequest) URL() *url.URL                     { return r.u }
  func (r webRequest) Method() string                    { return r.method }
  func (r webRequest) Transport() newrelic.TransportType { return r.transport }
  
  func eventWebRequest(event interface{}) newrelic.WebRequest {
  	var path string
  	var request webRequest
  	var headers map[string]string
  
  	switch r := event.(type) {
  	case events.APIGatewayProxyRequest:
  		request.method = r.HTTPMethod
  		path = r.Path
  		headers = r.Headers
  	case events.ALBTargetGroupRequest:
  		// https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#receive-event-from-load-balancer
  		request.method = r.HTTPMethod
  		path = r.Path
  		headers = r.Headers
  	default:
  		return nil
  	}
  
  	request.header = make(http.Header, len(headers))
  	for k, v := range headers {
  		request.header.Set(k, v)
  	}
  
  	var host string
  	if port := request.header.Get("X-Forwarded-Port"); port != "" {
  		host = ":" + port
  	}
  	request.u = &url.URL{
  		Path: path,
  		Host: host,
  	}
  
  	proto := strings.ToLower(request.header.Get("X-Forwarded-Proto"))
  	switch proto {
  	case "https":
  		request.transport = newrelic.TransportHTTPS
  	case "http":
  		request.transport = newrelic.TransportHTTP
  	default:
  		request.transport = newrelic.TransportUnknown
  	}
  
  	return request
  }
  
  func eventResponse(event interface{}) *response {
  	var code int
  	var headers map[string]string
  
  	switch r := event.(type) {
  	case events.APIGatewayProxyResponse:
  		code = r.StatusCode
  		headers = r.Headers
  	case events.ALBTargetGroupResponse:
  		code = r.StatusCode
  		headers = r.Headers
  	default:
  		return nil
  	}
  	hdr := make(http.Header, len(headers))
  	for k, v := range headers {
  		hdr.Add(k, v)
  	}
  	return &response{
  		code:   code,
  		header: hdr,
  	}
  }
  