/*
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 (
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"path"
	"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
}

// 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
}
