func GetTrip(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	tId := p.ByName("trip_id")
	checkID, _ := strconv.Atoi(tId)
	var tripData structure.DataStorage
	findTarget := false

	for key, value := range hmap {
		if key == checkID {
			tripData = value
			findTarget = true
		}
	}

	if findTarget == false {
		w.WriteHeader(404)
		return
	}

	tripResponse := structure.TripResponse{}
	tripResponse.Id = tripData.Id
	tripResponse.Status = tripData.Status
	tripResponse.Starting_from_location_id = tripData.Starting_from_location_id
	tripResponse.Best_route_location_id = tripData.Best_route_location_id
	tripResponse.Total_uber_costs = tripData.Total_uber_costs
	tripResponse.Total_distance = tripData.Total_distance
	tripResponse.Total_uber_duration = tripData.Total_uber_duration

	trip, _ := json.Marshal(tripResponse)
	w.WriteHeader(200)
	fmt.Fprintf(w, "%s", trip)
}
func CreateTrip(rw http.ResponseWriter, req *http.Request, p httprouter.Params) {
	var tripRequest structure.TripRequest
	json.NewDecoder(req.Body).Decode(&tripRequest)

	tripData := structure.DataStorage{}
	tripResponse := structure.TripResponse{}
	tripResponse.Id = getID()
	tripResponse.Status = "planning"
	tripResponse.Starting_from_location_id = tripRequest.Starting_from_location_id
	tripResponse.Best_route_location_id = tripRequest.Location_ids

	getBestRoute(&tripResponse, &tripData, tripRequest.Starting_from_location_id, tripRequest.Location_ids)

	hmap[tripResponse.Id] = tripData

	trip, _ := json.Marshal(tripResponse)
	rw.Header().Set("Content-Type", "application/json")
	rw.WriteHeader(201)
	fmt.Fprintf(rw, "%s", trip)
}
func getBestRoute(tripResponse *structure.TripResponse, tripData *structure.DataStorage, originId bson.ObjectId, targetId []bson.ObjectId) {
	pmtTarget, err := permutation.NewPerm(targetId, nil)
	if err != nil {
		fmt.Println(err)
		return
	}
	res := make([][]bson.ObjectId, 0, 0)
	routePrice := make([]int, 0, 0)
	routeDuration := make([]int, 0, 0)
	routeDistance := make([]float64, 0, 0)
	curPrice := 0
	curDuration := 0
	curDistance := 0.0
	for result, err := pmtTarget.Next(); err == nil; result, err = pmtTarget.Next() {
		for i := 0; i <= len(result.([]bson.ObjectId)); i++ {
			var startLat float64
			var startLng float64
			var endLat float64
			var endLng float64
			minPrice := 0
			minDuration := 0
			minDistance := 0.0
			response := structure.Response{}
			if i == 0 {
				if err := session.DB("cmpe273_project").C("hello").FindId(originId).One(&response); err != nil {
					return
				}
				startLat = response.Coordinate.Lat
				startLng = response.Coordinate.Lng

				if err := session.DB("cmpe273_project").C("hello").FindId((result.([]bson.ObjectId))[i]).One(&response); err != nil {
					return
				}
				endLat = response.Coordinate.Lat
				endLng = response.Coordinate.Lng
			} else if i == len(result.([]bson.ObjectId)) {
				if err := session.DB("cmpe273_project").C("hello").FindId((result.([]bson.ObjectId))[i-1]).One(&response); err != nil {
					return
				}
				startLat = response.Coordinate.Lat
				startLng = response.Coordinate.Lng

				if err := session.DB("cmpe273_project").C("hello").FindId(originId).One(&response); err != nil {
					return
				}
				endLat = response.Coordinate.Lat
				endLng = response.Coordinate.Lng
			} else {
				if err := session.DB("cmpe273_project").C("hello").FindId((result.([]bson.ObjectId))[i-1]).One(&response); err != nil {
					return
				}
				startLat = response.Coordinate.Lat
				startLng = response.Coordinate.Lng

				if err := session.DB("cmpe273_project").C("hello").FindId((result.([]bson.ObjectId))[i]).One(&response); err != nil {
					return
				}
				endLat = response.Coordinate.Lat
				endLng = response.Coordinate.Lng
			}

			urlLeft := "https://api.uber.com/v1/estimates/price?"
			// Server token cannot be told to others
			urlRight := "start_latitude=" + strconv.FormatFloat(startLat, 'f', -1, 64) + "&start_longitude=" + strconv.FormatFloat(startLng, 'f', -1, 64) + "&end_latitude=" + strconv.FormatFloat(endLat, 'f', -1, 64) + "&end_longitude=" + strconv.FormatFloat(endLng, 'f', -1, 64) + "&server_token=PLEASE PUT YOUR OWN SERVER TOKEN HERE"
			urlFormat := urlLeft + urlRight

			getPrices, err := http.Get(urlFormat)
			if err != nil {
				fmt.Println("Get Prices Error", err)
				panic(err)
			}

			var data structure.UberAPIResponse
			json.NewDecoder(getPrices.Body).Decode(&data)
			minPrice = data.Prices[0].LowEstimate
			minDuration = data.Prices[0].Duration
			minDistance = data.Prices[0].Distance
			for i := 0; i < len(data.Prices); i++ {
				if minPrice > data.Prices[i].LowEstimate && data.Prices[i].LowEstimate > 0 {
					minPrice = data.Prices[i].LowEstimate
					minDuration = data.Prices[i].Duration
					minDistance = data.Prices[i].Distance
				}
			}
			curPrice = curPrice + minPrice
			curDuration = curDuration + minDuration
			curDistance = curDistance + minDistance
		}

		routePrice = AppendInt(routePrice, curPrice)
		routeDuration = AppendInt(routeDuration, curDuration)
		routeDistance = AppendFloat(routeDistance, curDistance)

		fmt.Println(curPrice)
		fmt.Println(curDuration)
		fmt.Println(curDistance)
		curPrice = 0
		curDuration = 0
		curDistance = 0.0
		res = AppendBsonId(res, result.([]bson.ObjectId))
		fmt.Println(pmtTarget.Index(), result.([]bson.ObjectId))
	}
	index := 0
	curPrice = 1000
	for i := 0; i < len(routePrice); i++ {
		if curPrice > routePrice[i] {
			curPrice = routePrice[i]
			index = i
		}
	}
	fmt.Println("The best route of this trip is: ")
	fmt.Println(res[index])
	fmt.Println(routePrice[index])
	fmt.Println(routeDuration[index])
	fmt.Println(routeDistance[index])

	tripResponse.Best_route_location_id = res[index]
	tripResponse.Total_distance = routeDistance[index]
	tripResponse.Total_uber_costs = routePrice[index]
	tripResponse.Total_uber_duration = routeDuration[index]
	tripData.Id = tripResponse.Id
	tripData.Index = 0
	tripData.Status = tripResponse.Status
	tripData.Starting_from_location_id = tripResponse.Starting_from_location_id
	tripData.Best_route_location_id = res[index]
	tripData.Total_uber_costs = tripResponse.Total_uber_costs
	tripData.Total_uber_duration = tripResponse.Total_uber_duration
	tripData.Total_distance = tripResponse.Total_distance
}