/*
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 utils contains common BookingService based helper functions.
package utils

import (
	"crypto/md5"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"path"
	"sort"
	"strings"

	"github.com/golang/protobuf/jsonpb"
	"github.com/golang/protobuf/proto"
	"github.com/google/go-cmp/cmp"

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

// SlotKey is a struct representing a unique service.
type SlotKey struct {
	MerchantID string
	ServiceID  string
	StaffID    string
	RoomID     string
}

// LogFlow is a convenience function for logging common flows..
func LogFlow(f string, status string) {
	log.Println(strings.Join([]string{"\n##########\n", status, f, "Flow", "\n##########"}, " "))
}

func parseServiceFeed(serviceFeed string) ([]*fpb.Service, error) {
	var feed fpb.ServiceFeed
	content, err := ioutil.ReadFile(serviceFeed)
	if err != nil {
		return nil, fmt.Errorf("unable to read input file: %v", err)
	}
	if path.Ext(serviceFeed) == ".json" {
		if err := jsonpb.UnmarshalString(string(content), &feed); err != nil {
			return nil, fmt.Errorf("unable to parse feed as json: %v", err)
		}
	}
	if path.Ext(serviceFeed) == ".pb3" {
		if err := proto.Unmarshal(content, &feed); err != nil {
			return nil, fmt.Errorf("unable to parse feed as pb3: %v", err)
		}
	}

	if services := feed.GetService(); len(services) != 0 {
		return services, nil
	}
	return nil, errors.New("service feed is empty. At least one service must be present in feed")
}

func merchantService(merchantID, serviceID string) string {
	return strings.Join([]string{merchantID, serviceID}, "||")
}

func buildLineItem(availability *fpb.Availability, tickets []*fpb.TicketType) *mpb.LineItem {
	// If no ticket types return nil as there is nothing to build.
	if len(tickets) == 0 {
		return nil
	}

	// Treated as a set.
	ticketMap := make(map[string]*fpb.TicketType)
	for _, ticketType := range tickets {
		if _, ok := ticketMap[ticketType.GetTicketTypeId()]; !ok {
			// Ticket type ids should be unique to a merchant service pair.
			// If they're not unique they will get dropped silently here.
			// We enforce minimal feed validation in the test client so it's
			// up to you to ensure UIDs.
			ticketMap[ticketType.GetTicketTypeId()] = ticketType
		}
	}

	filteredTickets := tickets
	if len(availability.GetTicketTypeId()) != 0 {
		// Clear slice but preserve allocated memory.
		filteredTickets = filteredTickets[:0]
		for _, ticketTypeID := range availability.GetTicketTypeId() {
			if ticketType, ok := ticketMap[ticketTypeID]; ok {
				filteredTickets = append(filteredTickets, ticketType)
			}
		}
	}

	// If no ticket types return nil as there is nothing to build.
	if len(filteredTickets) == 0 {
		return nil
	}

	lineItem := &mpb.LineItem{
		ServiceId:   availability.GetServiceId(),
		StartSec:    availability.GetStartSec(),
		DurationSec: availability.GetDurationSec(),
		Price:       &mpb.Price{},
	}
	for i := 0; i < int(availability.GetSpotsOpen()); i++ {
		// This is deterministic which is fine given that we just want to get a mix of ticket types.
		ticketTypeIndex := rand.Intn(len(filteredTickets))
		// Calculate price of line item.
		if lineItem.GetPrice().GetCurrencyCode() == "" && filteredTickets[ticketTypeIndex].GetPrice().GetCurrencyCode() != "" {
			lineItem.Price.CurrencyCode = filteredTickets[ticketTypeIndex].GetPrice().GetCurrencyCode()
		}
		lineItem.Price.PriceMicros += filteredTickets[ticketTypeIndex].GetPrice().GetPriceMicros()

		// Add ticket to line item.
		lineItem.Tickets = append(lineItem.Tickets, &mpb.LineItem_OrderedTickets{
			TicketId: filteredTickets[ticketTypeIndex].GetTicketTypeId(),
			Count:    1,
		})
	}

	return lineItem
}

// MerchantLineItemMapFrom attempts to build a collection of LineItems from a service and availability feed.
func MerchantLineItemMapFrom(serviceFeed, availabilityFeed string, testSlots int) (map[string][]*mpb.LineItem, error) {
	services, err := parseServiceFeed(serviceFeed)
	if err != nil {
		return nil, err
	}

	feedHasTicketType := false
	serviceTicketTypeMap := make(map[string][]*fpb.TicketType)
	for _, service := range services {
		merchantServiceID := merchantService(service.GetMerchantId(), service.GetServiceId())
		for _, ticket := range service.GetTicketType() {
			// TicketType can't have an empty price message or ticket_type_id. If it does it's excluded from map.
			if ticket.GetPrice() == nil || len(ticket.GetTicketTypeId()) == 0 || cmp.Diff(fpb.Price{}, *ticket.GetPrice(), cmp.Comparer(proto.Equal)) == "" {
				continue
			}

			if _, ok := serviceTicketTypeMap[merchantServiceID]; !ok {
				serviceTicketTypeMap[merchantServiceID] = []*fpb.TicketType{}
			}
			feedHasTicketType = true
			serviceTicketTypeMap[merchantServiceID] = append(serviceTicketTypeMap[merchantServiceID], ticket)
		}
	}

	if !feedHasTicketType {
		return nil, errors.New("no valid ticket types found in service feed, please update service feed and retry")
	}

	availabilities, err := AvailabilityFrom(availabilityFeed, testSlots)
	if err != nil {
		return nil, err
	}

	merchantLineItemMap := make(map[string][]*mpb.LineItem)
	for _, availability := range availabilities {
		merchantServiceID := merchantService(availability.GetMerchantId(), availability.GetServiceId())
		if tickets, ok := serviceTicketTypeMap[merchantServiceID]; ok {
			lineItem := buildLineItem(availability, tickets)
			// If lineItem can't be built, don't include in map
			if lineItem == nil {
				continue
			}
			merchantLineItemMap[availability.GetMerchantId()] = append(merchantLineItemMap[availability.GetMerchantId()], lineItem)
		}
	}

	return merchantLineItemMap, nil
}

// AvailabilityFrom parses the file specified in availabilityFeed, returning a random permutation of availability data, maximum entries specified in testSlots
func AvailabilityFrom(availabilityFeed string, testSlots int) ([]*fpb.Availability, error) {
	LogFlow("Parse Input Feed", "Start")
	defer LogFlow("Parse Input Feed", "End")

	var feed fpb.AvailabilityFeed
	content, err := ioutil.ReadFile(availabilityFeed)
	if err != nil {
		return nil, fmt.Errorf("unable to read input file: %v", err)
	}
	if path.Ext(availabilityFeed) == ".json" {
		if err := jsonpb.UnmarshalString(string(content), &feed); err != nil {
			return nil, fmt.Errorf("unable to parse feed as json: %v", err)
		}
	}
	if path.Ext(availabilityFeed) == ".pb3" {
		if err := proto.Unmarshal(content, &feed); err != nil {
			return nil, fmt.Errorf("unable to parse feed as pb3: %v", err)
		}
	}

	var finalAvailability []*fpb.Availability
	var rawAvailability []*fpb.Availability
	for _, sa := range feed.GetServiceAvailability() {
		rawAvailability = append(rawAvailability, sa.GetAvailability()...)
	}
	if len(rawAvailability) == 0 || testSlots == 0 {
		return finalAvailability, errors.New("no valid availability in feed, exiting workflows")
	}
	if len(rawAvailability) <= testSlots {
		finalAvailability = rawAvailability
	} else {
		nums := rand.Perm(len(rawAvailability))[0:testSlots]
		for _, n := range nums {
			finalAvailability = append(finalAvailability, rawAvailability[n])
		}
	}
	log.Printf("Selected %d slots out of a possible %d", len(finalAvailability), len(rawAvailability))
	return finalAvailability, nil
}

// ValidateBooking performs granular comparisons between all got and want Bookings.
func ValidateBooking(got, want *mpb.Booking) error {
	if got.GetBookingId() == "" {
		return errors.New("booking_id is empty")
	}
	if diff := cmp.Diff(got.GetSlot(), want.GetSlot(), cmp.Comparer(proto.Equal)); diff != "" {
		return fmt.Errorf("slots differ (-got +want)\n%s", diff)
	}
	// UserId is the only required field for the partner to return.
	if diff := cmp.Diff(got.GetUserInformation().GetUserId(), want.GetUserInformation().GetUserId()); diff != "" {
		return fmt.Errorf("users differ (-got +want)\n%s", diff)
	}
	if diff := cmp.Diff(got.GetPaymentInformation(), want.GetPaymentInformation(), cmp.Comparer(proto.Equal)); diff != "" {
		return fmt.Errorf("payment information differs (-got +want)\n%s", diff)
	}
	// BookingStatus_CONFIRMED is the default case unless want overrides it.
	wantStatus := mpb.BookingStatus_CONFIRMED
	if want.GetStatus() != mpb.BookingStatus_BOOKING_STATUS_UNSPECIFIED {
		wantStatus = want.GetStatus()
	}
	if diff := cmp.Diff(got.GetStatus(), wantStatus); diff != "" {
		return fmt.Errorf("status differs (-got +want)\n%s", diff)
	}
	return nil
}

// ValidateLineItems performs granular comparisons between got and want LineItem arrays.
func ValidateLineItems(got, want []*mpb.LineItem, confirmStatus bool) error {
	if len(got) != len(want) {
		return fmt.Errorf("number of LineItems differ got %d want %d", len(got), len(want))
	}

	for _, lineItem := range got {
		orderTickets := OrderedTickets(lineItem.GetTickets())
		sort.Sort(orderTickets)
		lineItem.Tickets = orderTickets
	}
	for _, lineItem := range want {
		orderTickets := OrderedTickets(lineItem.GetTickets())
		sort.Sort(orderTickets)
		lineItem.Tickets = orderTickets

		if confirmStatus {
			lineItem.Status = mpb.BookingStatus_CONFIRMED
		}
	}
	sort.Sort(LineItems(got))
	sort.Sort(LineItems(want))

	if diff := cmp.Diff(got, want, cmp.Comparer(proto.Equal)); diff != "" {
		return fmt.Errorf("LineItems differ (-got +want)\n%s", diff)
	}

	return nil
}

// ValidateOrder performs granular comparisons between got and want Order messages.
// Params are purposely copied.
func ValidateOrder(got, want mpb.Order) error {
	if got.GetOrderId() == "" {
		return fmt.Errorf("no order id provided for Order %v", got)
	}
	want.OrderId = got.GetOrderId()

	if err := ValidateLineItems(got.GetItem(), want.GetItem(), true); err != nil {
		return err
	}

	// LineItems okay. Remove, free memory, and compare rest of proto.
	want.Item = nil
	got.Item = nil
	if diff := cmp.Diff(got, want, cmp.Comparer(proto.Equal)); diff != "" {
		return fmt.Errorf("order protos differ. LineItems excluded, already validated. (-got +want)\n%s", diff)
	}

	return nil
}

// ValidateOrders performs simple comparisons and set up before forwarding orders
// individually to ValidateOrder.
func ValidateOrders(got, want Orders) error {
	if len(got) != len(want) {
		return fmt.Errorf("number of Orders differ got %d want %d", len(got), len(want))
	}
	sort.Sort(got)
	sort.Sort(want)

	var errorStrings []string
	for i := 0; i < len(got); i++ {
		if err := ValidateOrder(*got[i], *want[i]); err != nil {
			errorStrings = append(errorStrings, err.Error())
		}
	}

	if len(errorStrings) != 0 {
		return errors.New(strings.Join(errorStrings, "\n"))
	}
	return nil
}

func hashLineItemByTicketIds(l *mpb.LineItem) string {
	var uID []string
	for _, ticket := range l.GetTickets() {
		uID = append(uID, ticket.GetTicketId())
	}
	return fmt.Sprintf("%x", md5.Sum([]byte(strings.Join(uID, `|`))))
}

// Orders is a convenience type for an Orders array
type Orders []*mpb.Order

func (o Orders) Len() int {
	return len(o)
}

func (o Orders) Less(i, j int) bool {
	return o[i].GetOrderId() < o[j].GetOrderId()
}

func (o Orders) Swap(i, j int) {
	o[i], o[j] = o[j], o[i]
}

// OrderedTickets is a convenience type for an OrderedTickets array
type OrderedTickets []*mpb.LineItem_OrderedTickets

func (ot OrderedTickets) Len() int {
	return len(ot)
}

func (ot OrderedTickets) Less(i, j int) bool {
	return ot[i].GetTicketId() < ot[j].GetTicketId()
}

func (ot OrderedTickets) Swap(i, j int) {
	ot[i], ot[j] = ot[j], ot[i]
}

// LineItems is a convenience type for a LineItem array
// This sort interface defined below should be used iff
// OrderedTickets have already been sorted AND
// ticket ids are UIDs
type LineItems []*mpb.LineItem

func (l LineItems) Len() int {
	return len(l)
}

func (l LineItems) Less(i, j int) bool {
	return hashLineItemByTicketIds(l[i]) < hashLineItemByTicketIds(l[j])
}

func (l LineItems) Swap(i, j int) {
	l[i], l[j] = l[j], l[i]
}

// BuildSlotFrom creates a bookingservice slot from an feed availability record.
func BuildSlotFrom(a *fpb.Availability) (*mpb.Slot, error) {
	r := a.GetResources()
	return &mpb.Slot{
		MerchantId:      a.GetMerchantId(),
		ServiceId:       a.GetServiceId(),
		StartSec:        a.GetStartSec(),
		DurationSec:     a.GetDurationSec(),
		AvailabilityTag: a.GetAvailabilityTag(),
		Resources: &mpb.ResourceIds{
			StaffId:   r.GetStaffId(),
			RoomId:    r.GetRoomId(),
			PartySize: r.GetPartySize(),
		},
	}, nil
}

// BuildMerchantServiceMap creates a key value pair of unique services to all of their availability slots.
func BuildMerchantServiceMap(av []*fpb.Availability) map[SlotKey][]*fpb.Availability {
	m := make(map[SlotKey][]*fpb.Availability)
	for _, a := range av {
		key := SlotKey{
			MerchantID: a.GetMerchantId(),
			ServiceID:  a.GetServiceId(),
			StaffID:    a.GetResources().GetStaffId(),
			RoomID:     a.GetResources().GetRoomId(),
		}
		m[key] = append(m[key], a)
	}
	return m
}
