/*
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.
	var credentials string
	if credentialsFile != "" {
		data, err := ioutil.ReadFile(credentialsFile)
		if err != nil {
			return nil, err
		}
		credentials = "Basic " + base64.StdEncoding.EncodeToString([]byte(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: credentials,
		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, &idemResp); 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)
}
