/*
Copyright 2017 Google Inc.

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

https://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.
*/

// Package api contains validation wrappers over BookingService endpoints.
package api

import (
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"encoding/base64"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/golang/protobuf/jsonpb"
	"github.com/golang/protobuf/proto"
	"github.com/google/go-cmp/cmp"
	"github.com/maps-booking-v3/utils"

	fpb "github.com/maps-booking-v3/feeds"
	mpb "github.com/maps-booking-v3/v3"
)

const (
	userID    = "0"
	firstName = "Jane"
	lastName  = "Doe"
	telephone = "+18007897890"
	email     = "test@example.com"
)

// HTTPConnection is a convenience struct for holding connection-related objects.
type HTTPConnection struct {
	client      *http.Client
	credentials string
	marshaler   *jsonpb.Marshaler
	baseURL     string
}

func setupCertConfig(caFile string, fullServerName string) (*tls.Config, error) {
	if caFile == "" {
		return nil, nil
	}
	b, err := ioutil.ReadFile(caFile)
	if err != nil {
		return nil, fmt.Errorf("failed to read root certificates file: %v", err)
	}
	cp := x509.NewCertPool()
	if !cp.AppendCertsFromPEM(b) {
		return nil, errors.New("failed to parse root certificates, please check your roots file (ca_file flag) and try again")
	}
	return &tls.Config{
		RootCAs:    cp,
		ServerName: fullServerName,
	}, nil
}

// InitHTTPConnection creates and returns a new HTTPConnection object
// with a given server address and username/password.
func InitHTTPConnection(serverAddr string, credentialsFile string, caFile string, fullServerName string) (*HTTPConnection, error) {
	// Set up username/password.
	data, err := ioutil.ReadFile(credentialsFile)
	if err != nil {
		return nil, err
	}
	usernamePassword := strings.Replace(string(data), "\n", "", -1)
	config, err := setupCertConfig(caFile, fullServerName)
	if err != nil {
		return nil, err
	}
	protocol := "http"
	if config != nil {
		protocol = "https"
	}
	return &HTTPConnection{
		client: &http.Client{
			Timeout:   10 * time.Second,
			Transport: &http.Transport{TLSClientConfig: config},
		},
		credentials: "Basic " + base64.StdEncoding.EncodeToString([]byte(usernamePassword)),
		marshaler:   &jsonpb.Marshaler{OrigName: true},
		baseURL:     protocol + "://" + serverAddr,
	}, nil
}

func (h HTTPConnection) getURL(rpcName string) string {
	if rpcName != "" {
		return h.baseURL + "/v3/" + rpcName
	}
	return h.baseURL
}

// Bookings is a convenience type for a booking array.
type Bookings []*mpb.Booking

func (b Bookings) Len() int {
	return len(b)
}

func (b Bookings) Less(i, j int) bool {
	return b[i].GetBookingId() < b[j].GetBookingId()
}

func (b Bookings) Swap(i, j int) {
	b[i], b[j] = b[j], b[i]
}

// HealthCheck performs a health check.
func HealthCheck(conn *HTTPConnection) error {
	utils.LogFlow("Health Check", "Start")
	defer utils.LogFlow("Health Check", "End")

	// See if we get a response.
	_, err := conn.client.Get(conn.getURL(""))
	if err != nil {
		return fmt.Errorf("could not complete health check: %v", err)
	}
	log.Println("health check success!")
	return nil
}

// sendRequest sets up and sends the relevant HTTP request to the server and returns the HTTP response.
func sendRequest(rpcName string, req string, conn *HTTPConnection) (string, error) {
	httpReq, err := http.NewRequest("POST", conn.getURL(rpcName), bytes.NewBuffer([]byte(req)))
	httpReq.Header.Set("Content-Type", "application/json")
	httpReq.Header.Set("Authorization", conn.credentials)
	log.Printf("%v Request. Sent(unix): %s, Request %v\n", rpcName, time.Now().UTC().Format(time.RFC850), httpReq)

	httpResp, err := conn.client.Do(httpReq)
	if err != nil {
		return "", fmt.Errorf("invalid response. %s yielded error: %v", rpcName, err)
	}
	defer httpResp.Body.Close()
	bodyBytes, err := ioutil.ReadAll(httpResp.Body)
	if err != nil {
		return "", fmt.Errorf("Could not read http response body")
	}
	bodyString := string(bodyBytes)
	log.Printf("%v Response. Received(unix): %s, Response %v\n", rpcName, time.Now().UTC().Format(time.RFC850), bodyString)
	return bodyString, nil
}

// CheckAvailability beforms a maps booking availability check on all supplied availability slots. This function
// will return all slots with a valid return.
func CheckAvailability(a *fpb.Availability, conn *HTTPConnection) error {
	slot, err := utils.BuildSlotFrom(a)
	if err != nil {
		return fmt.Errorf("unable to build request for check availability flow. err: %v, availability record: %v", err, a.String())
	}
	reqPB := &mpb.CheckAvailabilityRequest{
		Slot: slot,
	}
	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}
	httpResp, err := sendRequest("CheckAvailability", req, conn)
	if err != nil {
		return fmt.Errorf("invalid response. CheckAvailability yielded error: %v", err)
	}
	var resp mpb.CheckAvailabilityResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return fmt.Errorf("CheckAvailability: Could not parse HTTP response to pb3: %v", err)
	}

	if diff := cmp.Diff(resp.GetSlot(), slot, cmp.Comparer(proto.Equal)); diff != "" {
		return fmt.Errorf("invalid response. CheckAvailability slots differ (-got +want)\n%s", diff)
	}

	if resp.GetCountAvailable() == 0 {
		return errors.New("no count available in response")
	}

	return nil
}

// CreateBooking attempts to create bookings from availability slots.
func CreateBooking(a *fpb.Availability, conn *HTTPConnection) (*mpb.Booking, error) {
	slot, err := utils.BuildSlotFrom(a)
	if err != nil {
		return nil, fmt.Errorf("unable to build request for check availability flow. err: %v, availability record: %v", err, a.String())
	}

	gen := rand.New(rand.NewSource(time.Now().UnixNano()))
	// Lease currently unsupported.
	reqPB := &mpb.CreateBookingRequest{
		Slot: slot,
		UserInformation: &mpb.UserInformation{
			UserId:     userID,
			GivenName:  firstName,
			FamilyName: lastName,
			Telephone:  telephone,
			Email:      email,
		},
		PaymentInformation: &mpb.PaymentInformation{
			PrepaymentStatus: mpb.PrepaymentStatus_PREPAYMENT_NOT_PROVIDED,
		},
		IdempotencyToken: strconv.Itoa(gen.Intn(1000000)),
	}
	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return nil, fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}

	httpResp, err := sendRequest("CreateBooking", req, conn)
	if err != nil {
		return nil, fmt.Errorf("invalid response. CreateBooking  yielded error: %v", err)
	}
	var resp mpb.CreateBookingResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return nil, fmt.Errorf("CreateBooking: Could not parse HTTP response to pb3: %v", err)
	}

	if resp.GetBookingFailure() != nil {
		return nil, fmt.Errorf("invalid response. CreateBooking failed with booking failure %v", resp.GetBookingFailure())
	}

	b := resp.GetBooking()
	if iE := utils.ValidateBooking(b, &mpb.Booking{
		Slot:               reqPB.GetSlot(),
		UserInformation:    reqPB.GetUserInformation(),
		PaymentInformation: reqPB.GetPaymentInformation(),
	}); iE != nil {
		return nil, fmt.Errorf("invalid response. CreateBooking invalid: %s", iE.Error())
	}

	// Perform idempotency test.
	log.Printf("Idempotency check -- CreateBooking Request. Sent(unix): %s, Request %s", time.Now().UTC().Format(time.RFC850), reqPB.String())
	idemHTTPResp, err := sendRequest("CreateBooking", req, conn)
	if err != nil {
		return nil, fmt.Errorf("invalid response. Idempotency check yielded error: %v", err)
	}
	var idemResp mpb.CreateBookingResponse
	if err := jsonpb.UnmarshalString(idemHTTPResp, &resp); err != nil {
		return nil, fmt.Errorf("CreateBooking idem: Could not parse HTTP response to pb3: %v", err)
	}

	if diff := cmp.Diff(idemResp, resp); diff != "" {
		return b, fmt.Errorf("Idempotency check invalid (-got +want)\n%s", diff)
	}

	return b, nil
}

// ListBookings calls the maps booking ListBookings rpc and compares the return with all input bookings.
func ListBookings(tB Bookings, conn *HTTPConnection) (Bookings, error) {
	var out Bookings
	reqPB := &mpb.ListBookingsRequest{
		UserId: userID,
	}
	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return nil, fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}
	httpResp, err := sendRequest("ListBookings", req, conn)
	if err != nil {
		return nil, fmt.Errorf("invalid response. ListBookings yielded error: %v. Abandoning all booking from this flow", err)
	}
	var resp mpb.ListBookingsResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return nil, fmt.Errorf("ListBookings: Could not parse HTTP response to pb3: %v", err)
	}

	gB := Bookings(resp.GetBookings())
	if len(gB) != len(tB) {
		return out, fmt.Errorf("number of bookings differ, ListBookings invalid. Got: %d, Want: %d. Abandoning all bookings from this flow", len(gB), len(tB))
	}

	sort.Sort(gB)
	sort.Sort(tB)
	for i := 0; i < len(tB); i++ {
		if iE := utils.ValidateBooking(gB[i], tB[i]); iE != nil {
			log.Printf("ListBookings invalid, %s, abandoning slot %d/%d", iE.Error(), i, len(tB))
			continue
		}
		out = append(out, tB[i])
	}

	return out, nil
}

// GetBookingStatus checks that all input bookings are in an acceptable state.
func GetBookingStatus(b *mpb.Booking, conn *HTTPConnection) error {
	reqPB := &mpb.GetBookingStatusRequest{
		BookingId: b.GetBookingId(),
	}

	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}
	httpResp, err := sendRequest("GetBookingStatus", req, conn)
	if err != nil {
		return fmt.Errorf("invalid response. GetBookingStatus yielded error: %v", err)
	}
	var resp mpb.GetBookingStatusResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return fmt.Errorf("GetBookingsStatus: Could not parse HTTP response to pb3: %v", err)
	}

	if diff := cmp.Diff(resp.GetBookingStatus(), mpb.BookingStatus_CONFIRMED); diff != "" {
		return fmt.Errorf("invalid response. BookingStatus differ (-got +want)\n%s", diff)
	}

	return nil
}

// CancelBooking is a clean up method that cancels all supplied bookings.
func CancelBooking(b *mpb.Booking, conn *HTTPConnection) error {
	b.Status = mpb.BookingStatus_CANCELED
	reqPB := &mpb.UpdateBookingRequest{
		Booking: b,
	}
	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}
	httpResp, err := sendRequest("UpdateBooking", req, conn)
	if err != nil {
		return fmt.Errorf("invalid response. UpdateBooking yielded error: %v", err)
	}
	var resp mpb.UpdateBookingResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return fmt.Errorf("CancelBooking: Could not parse HTTP response to pb3: %v", err)
	}

	if iE := utils.ValidateBooking(resp.GetBooking(), reqPB.GetBooking()); iE != nil {
		return fmt.Errorf("invalid response. UpdateBooking: %s", iE.Error())
	}
	return nil
}

// Rescheduling will attempt to create a booking, update the booking, then cancel.
func Rescheduling(av []*fpb.Availability, conn *HTTPConnection) error {
	var slots []*fpb.Availability
	for _, v := range utils.BuildMerchantServiceMap(av) {
		// Need at least two slots for reschedule.
		if len(v) <= 1 {
			continue
		}
		slots = v
		break
	}

	if len(slots) == 0 {
		return errors.New("no suitable availability for rescheduling flow. exiting")
	}
	// Book first slot.
	newBooking, err := CreateBooking(slots[0], conn)
	if err != nil {
		return fmt.Errorf("could not complete booking, abandoning rescheduling flow: %v", err)
	}
	slot := newBooking.GetSlot()

	// New slot.
	lastAvailability := slots[len(slots)-1]
	slot.StartSec = lastAvailability.GetStartSec()
	slot.DurationSec = lastAvailability.GetDurationSec()

	reqPB := &mpb.UpdateBookingRequest{
		Booking: newBooking,
	}
	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return fmt.Errorf("Rescheduling UpdateBooking: Could not convert pb3 to json: %v", reqPB)
	}
	updateHTTPResp, err := sendRequest("UpdateBooking", req, conn)
	var resp mpb.CreateBookingResponse
	if err := jsonpb.UnmarshalString(updateHTTPResp, &resp); err != nil {
		return fmt.Errorf("Rescheduling UpdateBooking: Could not parse HTTP response to pb3: %v", err)
	}

	if iE := utils.ValidateBooking(resp.GetBooking(), newBooking); iE != nil {
		return fmt.Errorf("invalid response. UpdateBooking: %s, abandoning slot 1/1", iE.Error())
	}
	return CancelBooking(resp.GetBooking(), conn)
}
