// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"hash"
	"io"
	"log"
	"net/http"
	"strings"

	"golang.org/x/build/cmd/pubsubhelper/pubsubtypes"
)

func handleGithubWebhook(w http.ResponseWriter, r *http.Request) {
	if r.TLS == nil {
		http.Error(w, "HTTPS required", http.StatusBadRequest)
		return
	}
	body, err := validateGithubRequest(w, r)
	if err != nil {
		log.Printf("failed to validate github webhook request: %v", err)
		// But send a 200 OK anyway, so they don't queue up on
		// Github's side if they're real.
		return
	}

	var payload githubWebhookPayload
	if err := json.Unmarshal(body, &payload); err != nil {
		log.Printf("error unmarshalling payload: %v; payload=%s", err, body)
		// But send a 200 OK anyway. Our fault.
		return
	}
	back, _ := json.MarshalIndent(payload, "", "\t")
	log.Printf("github verified webhook: %s", back)

	if payload.Repository == nil || (payload.Issue == nil && payload.PullRequest == nil) {
		// Ignore.
		return
	}

	f := strings.Split(payload.Repository.FullName, "/")
	if len(f) != 2 {
		log.Printf("bogus repository name %q", payload.Repository.FullName)
		return
	}
	owner, repo := f[0], f[1]

	var issueNumber int
	if payload.Issue != nil {
		issueNumber = payload.Issue.Number
	}
	var prNumber int
	if payload.PullRequest != nil {
		prNumber = payload.PullRequest.Number
	}

	publish(&pubsubtypes.Event{
		GitHub: &pubsubtypes.GitHubEvent{
			Action:            payload.Action,
			RepoOwner:         owner,
			Repo:              repo,
			IssueNumber:       issueNumber,
			PullRequestNumber: prNumber,
		},
	})
}

// validateGithubRequest compares the signature in the request header with the body.
func validateGithubRequest(w http.ResponseWriter, r *http.Request) (body []byte, err error) {
	// Decode signature header.
	sigHeader := r.Header.Get("X-Hub-Signature")
	sigParts := strings.SplitN(sigHeader, "=", 2)
	if len(sigParts) != 2 {
		return nil, fmt.Errorf("Bad signature header: %q", sigHeader)
	}
	var h func() hash.Hash
	switch alg := sigParts[0]; alg {
	case "sha1":
		h = sha1.New
	case "sha256":
		h = sha256.New
	default:
		return nil, fmt.Errorf("Unsupported hash algorithm: %q", alg)
	}
	gotSig, err := hex.DecodeString(sigParts[1])
	if err != nil {
		return nil, err
	}

	body, err = io.ReadAll(http.MaxBytesReader(w, r.Body, 5<<20))
	if err != nil {
		return nil, err
	}
	// TODO(golang/go#37171): find a cleaner solution than using a global
	mac := hmac.New(h, []byte(*webhookSecret))
	mac.Write(body)
	expectSig := mac.Sum(nil)

	if !hmac.Equal(gotSig, expectSig) {
		return nil, fmt.Errorf("Invalid signature %X, want %x", gotSig, expectSig)
	}
	return body, nil
}

type githubWebhookPayload struct {
	Action      string             `json:"action"`
	Repository  *githubRepository  `json:"repository"`
	Issue       *githubIssue       `json:"issue"`
	PullRequest *githubPullRequest `json:"pull_request"`
}

type githubRepository struct {
	FullName string `json:"full_name"` // "golang/go"
}

type githubIssue struct {
	URL    string `json:"url"`    // https://api.github.com/repos/baxterthehacker/public-repo/issues/2
	Number int    `json:"number"` // 2
}

type githubPullRequest struct {
	URL    string `json:"url"`    // https://api.github.com/repos/baxterthehacker/public-repo/pulls/8
	Number int    `json:"number"` // 8
}
