/*
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"
	"strconv"
	"strings"
	"time"

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

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

// 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##########"}, " "))
}

// 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 *mpb.Booking, 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
}

// BuildIdempotencyToken creates a unique token based on the slot and user attempting to book the slot.
func BuildIdempotencyToken(a *fpb.Availability, u string) string {
	r := a.GetResources()
	parts := []string{a.GetMerchantId(), a.GetServiceId(), strconv.FormatInt(a.GetStartSec(), 10), strconv.FormatInt(a.GetDurationSec(), 10), r.GetStaffId(), r.GetRoomId(), u}
	key := strings.Join(parts, "")
	return fmt.Sprintf("%x", md5.Sum([]byte(key)))
}

// BuildSlotFrom creates a bookingservice slot from an feed availability record.
func BuildSlotFrom(a *fpb.Availability) (*mpb.Slot, error) {
	startTime, err := ptypes.TimestampProto(time.Unix(a.GetStartSec(), 0))
	if err != nil {
		return nil, err
	}
	r := a.GetResources()
	return &mpb.Slot{
		MerchantId:      a.GetMerchantId(),
		ServiceId:       a.GetServiceId(),
		StartTime:       startTime,
		Duration:        ptypes.DurationProto(time.Duration(a.GetDurationSec()) * time.Second),
		AvailabilityTag: a.GetAvailabilityTag(),
		Resources: &mpb.Resources{
			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
}
