<?php

class MultiModalApi extends Api
{
    public $apiName = 'multimodal';
    const CACHE_TIMEOUT = 1800; // 30 minutes

    public function indexAction() {
        syslog(LOG_WARNING,'MultiModalApi::indexAction()');
        // 16279
        $message = "Unexpected error";
        $leg_id = $this->requestParams["leg_id"] ?? 0;
        $country = $this->requestParams["country"] ?? 'SG';
        $member_id = $this->requestParams["member_id"] ?? 0;
        $advice_id = 0;
        try {
            if ($leg_id<1) {
                throw new Exception('Invalid trip leg ID');
            }
            $db = new Db();
            list ($leg, $err) = MultiModal::getLegById($db->getConnect(), (int)$leg_id);
            if (!$leg || !isset($leg['id']) || $leg['id']<1) {
                throw new Exception($err!=""?$err:'No trip leg found');
            }
            syslog(LOG_WARNING,'111111111');
            list ($advice, $err) = MultiModal::getLegAdviceGoogleById($db->getConnect(), (int)$leg['parsedemail_item_advice_google_id']);
            if ($advice && $advice['id']>0) {
                $advice_id = $advice['id'];
            } else {
                throw new Exception($err!=""?$err:'No google advice found');
            }
            // DEBUG
            $country = Geocode::mockGPSCountry($db->getConnect(), $member_id, $country, 'default');

            list ($legs, $err) = MultiModal::getAdviceLegs($db->getConnect(), $advice_id);
            return MultiModalApi::processLegs($db, $legs, $advice_id, $country);
        } catch (Exception $e) {
            syslog(LOG_WARNING,json_encode($e));
            $message = $e->getMessage();
        }
        return $this->response(
            array(
                'error' => $message
            ), 500);
    }

    protected function processSteps($db, $leg, $ok) {
        list ($steps, $err) = MultiModal::getLegSteps($db->getConnect(), (int)$leg['id']);
        if ($steps || count($steps)>0) {
            $total = 0;
            $overview = []; 
            foreach ($steps as $key=>$step) {
                $leg['step_fares'][$step['sid']] = NULL;
                // We support BUS, SUBWAY, TAXI only (and Singapore...)
                if ($step['travel_mode']=='TAXI' || $step['travel_mode']=='SCOOTER' ||
                    ($step['travel_mode']=='TRANSIT' && isset($step['vehicle']) && 
                    ($step['vehicle']='BUS' || $step['vehicle']=='SUBWAY'))) {
                    if (isset($step['fare_raw']) && $step['fare_raw']!="") {
                        // OK
                        $total += (int)$step['fare_raw'];
                        $leg['step_fares'][$step['sid']] = (int)$step['fare_raw'];
                    } else {
                        // Not OK
                        $ok = false;
                        error_log('No quote for step_id='.$step['sid'].' traveling by '.(isset($step['vehicle'])?$step['vehicle']:"NO VEHICLE"));
                    }
                } else {
                    error_log('Unsupported travel mode: '.$step['travel_mode']."/".(isset($step['vehicle'])?$step['vehicle']:"NO VEHICLE"));
                }
                if (array_key_exists("polyline",$step)) {
                    $overview[] = $step["polyline"];
                }
                if (!array_key_exists('duration',$step) || $step['duration']<60) {
                    $step['duration'] = 60;
                }
                $steps[$key] = $step;
            }
            if ($leg['fare_raw']!=$total && $total>0) {
                error_log('Leg #'.$leg['id'].' total ('.$leg['fare_raw'].') != calculated ('.$total.')');
                $leg['fare_raw'] = $total;
            }
            if (count($overview)>0) {
                require_once('../common/Polyline.php');
                $leg["polyline"] = MultiModal::processPolyline($overview);
            }
        } else {
            error_log('No steps found for leg #'.$leg['id']);
        }
        return [$leg, $ok, $steps];
    }

    /**
     * Method GET
     * Get single record (by id)
     * http://DOMAIN/multimodal/1
     * @return string
     */
    public function viewAction() {
        //id must be the first parameter after /multimodal/x
        $id = array_shift($this->requestUri);

        if($id && (int)$id>0){
            $db = new Db();
            $tripOptions = Trips::getOptionsById($db->getConnect(), (int)$id);
            if(is_array($tripOptions) && count($tripOptions)>0) {
                /*$tripOptions = ActivityApi::processQuotesTripMultimodalOptions(
                    $db, $member_id, $country, $tripOptions);*/
                return $this->response(
                    array(
                        'id' => $id,
                        'count' => count($tripOptions),
                        'options' => $tripOptions
                    ), 200);
            }
        }
        return $this->response(
            array(
                'error'=> 'Data not found'
            ), 404);
    }

    public function createAction() {
        syslog(LOG_WARNING,'MultiModalApi::createAction()');
        $message = "Failed to run multi-modal router";
        $origin = $this->requestParams["origin"] ?? 0;
        $destination = $this->requestParams["destination"] ?? 0;
        $country = $this->requestParams["country"] ?? 'SG';
        $no_cache = $this->requestParams["no_cache"] ?? false;
        $member_id = $this->requestParams["member_id"] ?? 0;
        $cache_timeout = $this->requestParams["cache_timeout"] ?? MultiModalApi::CACHE_TIMEOUT;
        $distance = $this->requestParams["distance"] ?? 0;
        $duration = $this->requestParams["duration"] ?? 0;

        try {
            $db = new Db();

            // DEBUG
            $country = Geocode::mockGPSCountry($db->getConnect(), $member_id, $country, 'default');

            // Check country
            if ($country!='SG' && $country!='US') {
                throw new RuntimeException('Trips has not yet launched in your country. You can still track your travel activity and access exclusive deals. Start exploring!',500);
            }
            // Check input
            $addrOrigin = Address::getAddressById($db->getConnect(), (int)$origin);
            $addrDestination = Address::getAddressById($db->getConnect(), (int)$destination);
            if ($addrOrigin==NULL || $addrDestination==NULL) {
                throw new Exception('Invalid origin and/or destination address');
            }

            $checkOptions = [
                [
                    "type"=>1,
                    "geocode" => [
                        "lat" => $addrOrigin["latitude"],
                        "lng" => $addrOrigin["longitude"]
                    ]
                ]
            ];
            syslog(LOG_WARNING,'MultiModalApi: '.json_encode($checkOptions));
            $withinTheServiceArea = GeocodeApi::checkWithinTheServiceArea($country, $checkOptions, false);
            if ($withinTheServiceArea) {
                syslog(LOG_WARNING,'MultiModalApi: WITHIN SERVICE AREA!');
                $trip = MultiModalApi::multimodal(
                    $db, $addrOrigin, $addrDestination, $country, $no_cache, $member_id, $cache_timeout, $distance, $duration
                ); 
            } else {
                // Trip format
                syslog(LOG_WARNING,'MultiModalApi: IS NOT WITHIN SERVICE AREA!');
                $trip = ActivityApi::createTrip($db, $country, $duration, $distance, $addrOrigin["id"], $addrDestination["id"]);
            }
            
            /******* Start GOJEK ******/
            //$trip = MultiModalApi::processGojekOption($db, $member_id, $country, $trip);
            /******* End GOJEK ******/
            if ($country=='US') {
                $trip = MultiModalApi::processRidesharesOption($db, $member_id, $country, $trip);
            }

            if ($trip && count($trip)) {
                $trip = MultiModalFilter::sortTrip($trip);
                return $this->response($trip, 200);
            } else {
                $message = "Failed to process multimodal trip";
            }
        } catch (Exception $e) {
            error_log(json_encode($e));
            $message = $e->getMessage();
        }
        return $this->response(
            array(
                "error" => $message
            ), 500);
    }

    public static function processGojekOption($db, $member_id, $country, $trip) {
        $trips = ActivityApi::processGojekOption($db, $member_id, $country, [
            [
                'trip' => $trip
            ]
        ]);
        $n = count($trips) - 1;
        if ($n>0 && array_key_exists('rideshare',$trips[$n]) && is_array($trips[$n]['rideshare']) && count($trips[$n]['rideshare'])>10) {
            $gojek = $trips[$n]['rideshare'];
            $options = $gojek['options'];
            $leg = $options['legs'][0];
            $leg_fare = $options['leg_fare'][$leg['id']];
            $leg_steps = $options['leg_steps'][$leg['id']];
            $trip['options']['legs'][] = $leg; // Append GOJEK
            $trip['options']['leg_fare'][$leg['id']] = $leg_fare;
            $trip['options']['leg_steps'][$leg['id']] = $leg_steps;
            $trip['options']['routes'] = count($trip['options']['legs']);
        }
        return $trip;
    }

    public static function processRidesharesOption($db, $member_id, $country, $trip) {
        syslog(LOG_WARNING,"MultiModalApi::processRidesharesOption(\$db, $member_id, $country, \$trip)");
        $trips = ActivityApi::processRidesharesOption($db, $member_id, $country, [
            [
                'trip' => $trip
            ]
        ]);
        foreach ($trips as $item) {
            if (is_array($item) && array_key_exists('rideshare',$item) && is_array($item['rideshare']) && count($item['rideshare'])>10) {
                $rideshare = $item['rideshare'];
                $options = $rideshare['options'];
                $leg = $options['legs'][0];
                $leg_fare = $options['leg_fare'][$leg['id']];
                $leg_steps = $options['leg_steps'][$leg['id']];
                $trip['options']['legs'][] = $leg; // Append Rideshare
                $trip['options']['leg_fare'][$leg['id']] = $leg_fare;
                $trip['options']['leg_steps'][$leg['id']] = $leg_steps;
                $trip['options']['routes'] = count($trip['options']['legs']);
            } else {
                syslog(LOG_WARNING,"Invalid rideshare entry!");
            }
        }
        /*
        $n = count($trips) - 1;
        if ($n>0 && array_key_exists('rideshare',$trips[$n]) && is_array($trips[$n]['rideshare']) && count($trips[$n]['rideshare'])>10) {
            $rideshare = $trips[$n]['rideshare'];
            $options = $rideshare['options'];
            $leg = $options['legs'][0];
            $leg_fare = $options['leg_fare'][$leg['id']];
            $leg_steps = $options['leg_steps'][$leg['id']];
            $trip['options']['legs'][] = $leg; // Append Rideshare
            $trip['options']['leg_fare'][$leg['id']] = $leg_fare;
            $trip['options']['leg_steps'][$leg['id']] = $leg_steps;
            $trip['options']['routes'] = count($trip['options']['legs']);
        }*/
        return $trip;
    }

    public function multimodal($db, $addrOrigin, $addrDestination, $country, $no_cache, $member_id, $cache_timeout, $distance, $duration) {
        error_log('MultiModalApi::multimodal()');
        $trip = NULL;
        try {
            // id,address,latitude,longitude,timezone,geocoding_date,postal
            // 3,'97 Meyer Road, Singapore', 1.2833754, 103.8607264, 1, 2019-05-18, 018956
            if (!$no_cache) { // we can force to skip the cache...
                $trip = Trips::getByCoordinates(
                    $db->getConnect(), 
                    ['lat' => $addrOrigin['latitude'], 'lng' => $addrOrigin['longitude']],
                    ['lat' => $addrDestination['latitude'], 'lng' => $addrDestination['longitude']], 
                    1
                );
                if ($trip && $trip["id"]>0 && MultiModalApi::checkCache($db, $trip, $cache_timeout)) {
                    // Trip options
                    $trip["member_id"] = $member_id; // Pass along
                    $tripOptions = Trips::getOptionsById($db->getConnect(), $trip["id"]);
                    if(is_array($tripOptions) && count($tripOptions)>0) {

                        ActivityApi::debugTrips([['multimodal'=>['options'=>$tripOptions]]],'11111');

                        $tripOptions = ActivityApi::processQuotesTripMultimodalOptions($db, $member_id, $country, $tripOptions);
                        $trip = array_merge($trip, array(
                            'count' => count($tripOptions),
                            'options' => $tripOptions,
                            'from_cache' => true
                        ));
                        
                        ActivityApi::debugTrips([['multimodal'=>$trip]],'11112');

                        $trip['country'] = $country;
                        $trip = MultiModalApi::processTrip($db, $trip, $country);

                        ActivityApi::debugTrips([['multimodal'=>$trip]],'11113');


                        throw new Exception('OK');
                    } else {
                        // Will need new trip options!
                        error_log('Trip parsedemail_item.id='.$trip["id"].' does not have options!');
                    }
                } else if ($trip && $trip["id"]>0) {
                    $trip = NULL; // cache miss - we will need a new trip!
                } // else trip was not found
            }
            // Create a new trip entry
            if ($trip==NULL || !isset($trip["id"])) {
                $data = [
                    'travel_date' => MultiModal::getDate($country),
			        'duration' => (int)$duration,
			        'cost_raw' => NULL,
			        'trackedemail_item_id' => NULL,
			        'cost' => NULL,
			        'distance' => $distance,
			        'transport_provider_id' => NULL,
			        'scheduled' => NULL,
			        'travel_date_end' => MultiModal::getDate($country),
			        'dup_id' => NULL,
			        'location_start_id' => $addrOrigin['id'],
			        'location_end_id' => $addrDestination['id'],
			        'private' => 't' /* this is a private entry without the source e-mail */
                ];
                list($id, $err) = Trips::create($db->getConnect(), $data);
                if ($id && $id>0) {
                    $trip = Trips::getById($db->getConnect(), $id);
                }
                if ($trip==NULL || !isset($trip["id"])) {
                    throw new Exception('Failed to create new trip record'.($err?": ${err}":""));
                }
            }
            // New directions
            $tripService = MultiModalApi::tripService($trip["id"], $country);
            //error_log(json_encode($tripService));
            if (is_array($tripService) && isset($tripService["travel_date"])) {
                $tripService["member_id"] = $member_id; // Pass along
                $tripService["country"] = $country;

                $tripService = MultiModalFilter::byDuration($tripService);
                
                ActivityApi::debugTrips([['multimodal'=>$tripService]],'11114'); 

                $tripService = MultiModalApi::processTrip($db, $tripService, $country);

                ActivityApi::debugTrips([['multimodal'=>$tripService]],'11115');

                $tripOptions = $tripService["options"];

                ActivityApi::debugTrips([['multimodal'=>$tripService]],'111');

                $tripOptions = ActivityApi::processQuotesTripMultimodalOptions(
                    $db, $member_id, $country, $tripOptions);
                $tripService["options"] =  $tripOptions;       
                $trip = $tripService;

                ActivityApi::debugTrips([['multimodal'=>$trip]],'112');

                $trip = MultiModalFilter::byCost($trip);
            }
        } catch (Exception $e) {
            error_log($e->getMessage());
        }
        return $trip;
    }

    protected function checkCache($db, $trip, $cache_timeout) {
        error_log('MultiModalApi::checkCache()');
        $advice = NULL;
        if (!is_array($trip) || $trip['id']<1) {
            error_log('No trip data to analyse => no cache!');
            return false;
        }
        list ($res, $err) = MultiModal::getLastGoogleAdviceByTrip($db->getConnect(),$trip['id']);
        error_log(json_encode($res));
        if ($res && $res['id']>0) {
            $advice = $res;
        } else {
            error_log('No parsedemail_item_advice_google record => no cache!');
            return false;
        }
        if ($advice['elapsed'] > $cache_timeout) {
            error_log('Cache expired! We will need a new advice!');
            return false;
        }
        return true;
    }

    protected function checkTaxiQuote($db, $trip, $country) {
        syslog(LOG_WARNING,"MultiModalApi::checkTaxiQuote(\$db, \$trip, $country)");
        try {
            // Do we have trip options?
            if (!isset($trip['options']) || !is_array($trip['options']) || !isset($trip['options']['legs'])) {
                error_log('Trip parsedemail_item.id='.$trip['id'].' has no options!');
                return $trip;
            }
            // Do we have a member_id?
            $member_id = 0;
            if (isset($trip["member_id"])) {
                $member_id = $trip["member_id"];
            }
            // Do we have transport providers?
            $transport_providers = [];
            list ($result, $error) = Geocode::getTransportProvidersByCountry(
                $db->getConnect(), $trip["country"]);
            if ($result==NULL || count($result)<1) {
                syslog(LOG_WARNING,"Failed to get transport providers: ".$error);
                return $trip;
            }
            foreach ($result as $f) {
                if ($trip["country"]!='SG' || $f["transport_provider_id"]==4) { // ComfortDelGro
                    $transport_providers[] = $f["transport_provider_id"];
                }
            }
            // Check leg steps for the taxi
            $n = count($trip['options']['legs']);
            for ($i=0; $i<$n; $i++) {
                $leg = $trip['options']['legs'][$i];
                $leg_id = $leg['id'];
                $leg_steps = $trip['options']['leg_steps'][$leg_id];
                $leg_fare = $trip['options']['leg_fare'][$leg_id];
                $m = count($leg_steps);
                $total = 0;
                for ($j=0; $j<$m; $j++) {
                    $step = $leg_steps[$j];
                    if ($step['travel_mode']=="TAXI") {
                        // Reverse geocode
                        list($origin, $err1) = GeocodeApi::reverseGeocode($db, $step["location_start_lat"], $step["location_start_lng"]);
                        list($destination, $err2) = GeocodeApi::reverseGeocode($db, $step["location_end_lat"], $step["location_end_lng"]);
                        if ($origin=='' || $destination=='') {
                            syslog(LOG_WARNING,'MultiModalApi::checkTaxiQuote() Reverse geocoding failed! From "'.$origin.'"('.$step["location_start_lat"].','.$step["location_start_lng"].') to "'.$destination.'"('.$step["location_end_lat"].','.$step["location_end_lng"].')');
                            continue;
                        }
                        syslog(LOG_WARNING,"origin='${origin}'");
                        syslog(LOG_WARNING,"destination='${destination}");
                        list($message,$code,$action,$data) = QuoteGroupApi::createReal(
                            $db, $origin, $destination, $member_id, $transport_providers, $country
                        );
                        if (is_array($data) && isset($data["id"]) && $data["id"]>0) {
                            syslog(LOG_WARNING,"QuoteGroup ID: ".$data["id"]);
                            $quoteGroupId = $data["id"];
                            // Check quote
                            $step["quote_group_id"] = $quoteGroupId;
                            sleep(3);
                            list($message,$code,$action,$data) = QuoteGroupApi::viewReal($db, $quoteGroupId);
                            if ($code==200 && isset($data["cost"]) && $data["cost"]>0) {
                                // TODO: double-check!
                                $step["fare_quote"] = ((int)(100*$data["cost"]));
                                if (!array_key_exists('fare_raw',$step) || $step['fare_raw']<$step["fare_quote"]) {
                                    $step['fare_raw'] = $step["fare_quote"];
                                } 
                                if ($leg_fare==NULL) $leg_fare = $step["fare_quote"];
                                else $leg_fare += $step["fare_quote"];
                            } else {
                                syslog(LOG_WARNING,"ERROR: ".$message);
                            }
                        } else {
                            syslog(LOG_WARNING,"ERROR: ".$message);
                        }
                    }
                    if (array_key_exists('fare_raw',$step) && $step['fare_raw']>0) {
                        $total += $step['fare_raw'];
                    }
                    if (!array_key_exists('duration',$step) || $step['duration']<60) {
                        $step['duration'] = 60;
                    }
                    $leg_steps[$j] = $step;
                }
                if (!array_key_exists('fare_raw',$leg) || $leg['fare_raw']<$leg_fare || $leg['fare_raw']<$total) {
                    $leg['fare_raw'] = $leg_fare>$total ? $leg_fare : $total;
                }
                $trip['options']['leg_fare'][$leg_id] = $leg_fare>$total ? $leg_fare : $total;
                $trip['options']['leg_steps'][$leg_id] = $leg_steps;
                $trip['options']['legs'][$i] = $leg;
            }
            //*/
        } catch (Exception $e) {
            syslog(LOG_WARNING,'MultiModalApi::checkTaxiQuote() EXCEPTION: '.$e->getMessage());
        }
        return $trip;
    }

    protected function processTrip($db, $trip, $country) {
        syslog(LOG_WARNING,'MultiModalApi::processTrip()');
        require_once('../common/Polyline.php');
        //error_log(json_encode($trip));

        ActivityApi::debugTrips([['multimodal'=>$trip]],'1111');

        if (array_key_exists('options',$trip) && is_array($trip['options']) && isset($trip['options']['legs'])) {
            if ($trip['options']['gid']<1) {
                // Save options...
                list($res, $err) = MultiModal::create($db->getConnect(), $trip);
                error_log($err);
                if ($res && $res['id']>0) {
                    $trip = $res;
                    // TODO: fix!
                    //unset($trip['error']);
                } else {
                    $message = $err!='' ? $err : 'Failed to save multi-modal option';
                    error_log($message);
                    $trip['error'] = $message;
                    $trip['options']['routes'] = count($trip['options']['legs']);
                    $trip = MultiModalApi::checkTaxiQuote($db, $trip, $country);
                    return $trip;
                }
            } else {
                error_log('DB record for options already exists');
            }
            // Schedule quote
            $trip = MultiModalApi::checkTaxiQuote($db, $trip, $country);
            $n = count($trip['options']['legs']);
            for ($i=0; $i<$n; $i++) {
                $leg = $trip['options']['legs'][$i];
                $leg_id = $leg['id'];
                $leg_steps = $trip['options']['leg_steps'][$leg_id];
                $leg_fare = $trip['options']['leg_fare'][$leg_id];
                // We must schedule leg fare quote...
                $m = count($leg_steps);
                $overview = [];
                for ($j=0; $j<$m; $j++) {
                    $step = $leg_steps[$j];
                    //"travel_mode": "TRANSIT"
                    //"vehicle": "BUS",
                    //"line": "", <------------- WTF?
                    if ($step['travel_mode']=="SCOOTER") {
                        $polyline = [];
                        // Get directions
                        $input = [
                            1 => [
                                "coordinates" => [
                                    "lat" => $trip["location_start_lat"],
                                    "lng" => $trip["location_start_lng"]
                                ]
                            ],
                            2 => [
                                "coordinates" => [
                                    "lat" => $trip["location_end_lat"],
                                    "lng" => $trip["location_end_lng"]
                                ]
                            ]
                        ];
                        $result = [
                            1 => [
                                "data" => [
                                    "location_start_lat" => $step["location_start_lat"],
                                    "location_start_lng" => $step["location_start_lng"],
                                    "location_end_lat" => $step["location_end_lat"],
                                    "location_end_lng" => $step["location_end_lng"]
                                ]
                            ]
                        ];
                        $options = ScooterApi::directions($db, $input, $result, []);
                        $step["route_overlay"] = isset($options["route_overlay"]) ? $options["route_overlay"][0] : [];
                        $step["polyline"] = $options["route_overlay"][0]["polyline"]; 
                        $polyline = $step["polyline"]; // TODO: merge with walking...
                        // Get quote
                        $scooter_time = $step['duration'];
                        $country = 'SG'; // Singapore only!
                        list($res,$err) = ScooterApi::quote($db, $scooter_time, $country);
                        if ($res && count($res)>0) {
                            $fare_raw = PHP_INT_MAX;
                            foreach ($res as $quote) {
                                if ($quote['pricing']['dropoff_anywhere']!=null) {
                                    $fare_raw = $quote['quote'] + $quote['pricing']['dropoff_anywhere'];
                                    break; // with this option we have Neuron only and that be it
                                }
                                if ($fare_raw > $quote['quote']) {
                                    $fare_raw = $quote['quote'];
                                }
                            }
                            if ($fare_raw == PHP_INT_MAX) {
                                $fare_raw = NULL; // we did not get any quote?
                            } else {
                                $fare_raw = (int)($fare_raw);
                            }
                            $trip['options']['leg_fare'][$leg_id] = $fare_raw;
                            $leg['fare_raw'] = $fare_raw;
                            $step['fare_raw'] = $fare_raw;
                        } 
                        $leg['polyline'] = $polyline;
                        $step['polyline'] = $polyline;                       
                    }
                    //error_log(json_encode($step));
                    $leg_steps[$j] = $step;
                    
                    // TODO: FIX!!!

                    if (array_key_exists("polyline",$step)) {
                        $overview[] = $step["polyline"];
                    }
                    
                }
                if (count($overview)>0) {
                    $leg["polyline"] = MultiModal::processPolyline($overview);
                }
                //syslog(LOG_WARNING,'$leg["polyline"] = '.$leg["polyline"]);
                $trip['options']['leg_steps'][$leg_id] = $leg_steps;
                $trip['options']['legs'][$i] = $leg;
            }
            $trip['options']['routes'] = count($trip['options']['legs']);
        } else {
            syslog(LOG_WARNING,'Trip parsedemail_item.id='.$trip['id'].' has no options!');
        }
        return $trip;
    }

    public function updateAction() {
        return $this->response(
            array(
                "error" => "Update error"
            ), 400);
    }

    public function deleteAction() {
        $res = 0;
        $message = "Delete error";
        $id = (int)array_shift($this->requestUri);
        if ($id>0) {
            $db = new Db();
            $res = MultiModal::delete($db->getConnect(), $id);
            if ($res>0) {
                return $this->response(array(
                    'id' => $id,
                    'result' => $res
                ), 200);
            } else {
                $message = "Delete failed";
            }
        } else {
            $message = "Invalid error";
        }
        return $this->response(
            array(
                "error" => $message,
                "result" => $res
            ), 500);
    }

    public function tripService($id, $country) {
        global $savvyext;
        $httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
        $oauth2_url = $savvyext->cfgReadChar('system.oauth2_url');
        error_log("MultiModalApi::tripService($id)");
        if ($country!='SG' && $country!='US') {
            throw new Exception('Unsupported country: '.$country);
        }
        // curl -d 'id=8907' -X POST {$oauth2_url}trips/
        $postdata = http_build_query(
            array(
                'id'=> $id,
                'country' => $country
            )
        );
        $url = $oauth2_url."trips";
        $opts = array(
            'http' => array(
                'method' => "POST",
                'timeout' => 60, /* 1 minute */
                'header'  => 
                    "Content-Type: application/x-www-form-urlencoded\r\n" .
                    "Accept: application/json\r\n" .
                    "Authorization: Server-Token ${httpAuthToken}\r\n",
                'content' => $postdata
            ),
            "ssl" => array(
              "verify_peer"=>false,
              "verify_peer_name"=>false,
            )
        );
        $context = stream_context_create($opts);
        error_log("started trips service call");
        $t = time();
        $body = file_get_contents($url, false, $context);
        error_log("complete trips service call: ".(time()-$t)." seconds");
        file_put_contents('/home/savvy/FloatWeb/adminsavvy/DEBUG/trips'.time().'.json',$body);
        $trip = json_decode($body,true);
        return $trip;
    }

    public function mytansportsgService($id) {
        global $savvyext;
        $httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
        $oauth2_url = $savvyext->cfgReadChar('system.oauth2_url');
        error_log("public function mytransportsgService($id)");
        // curl -d 'id=8907' -X POST $oauth2_url.'mytransportsg'/
        $postdata = http_build_query(
            array(
                'advice_id'=> $id
            )
        );
        $url = $oauth2_url."mytransportsg";
        $opts = array(
            'http' => array(
                'method' => "POST",
                'timeout' => 60, /* 1 minute */
                'header'  => 
                    "Content-Type: application/x-www-form-urlencoded\r\n" .
                    "Accept: application/json\r\n" .
                    "Authorization: Server-Token ${httpAuthToken}\r\n",
                'content' => $postdata
            ),
            "ssl" => array(
              "verify_peer"=>false,
              "verify_peer_name"=>false,
            )
        );
        $context = stream_context_create($opts);
        $body = file_get_contents($url, false, $context);
        $advice = json_decode($body,true);
        return $advice;
    }

    public function mytansportsgServiceLeg($id) {
        global $savvyext;
        $httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
        $oauth2_url = $savvyext->cfgReadChar('system.oauth2_url');
        error_log("public function mytransportsgServiceLeg($id)");
        $url = $oauth2_url."mytransportsg/" . $id;
        $opts = array(
            'http' => array(
                'method' => "GET",
                'timeout' => 60, /* 1 minute */
                'header'  =>
                    "Content-Type: application/x-www-form-urlencoded\r\n" .
                    "Accept: application/json\r\n" .
                    "Authorization: Server-Token ${httpAuthToken}\r\n",
            ),
            "ssl" => array(
                "verify_peer"=>false,
                "verify_peer_name"=>false,
            )
        );
        $context = stream_context_create($opts);
        $body = file_get_contents($url, false, $context);
        $advice = json_decode($body,true);
        return $advice;
    }

    public function bartService($db, $legs, $id) {
        $quotes = []; // We do not call the service as the data is presented after the initial call
        foreach ($legs as $leg_id=>$leg) {
            $total = 0;
            list ($res, $err) = MultiModal::getLegStepQuotes($db->getConnect(), $leg_id);
            if ($res && count($res)>0) {
                foreach ($res as $quote) {
                    $total += ((int)$f["fare_raw"]);
                }
            }
            $quotes[$leg_id] = [
                "total" => $total,
            ];
        }
        $result = [
            "code" => 0,
            "data" => $quotes
        ];
        return $result;
    }

    protected function processLegs($db, $legs, $advice_id, $country) {
        syslog(LOG_WARNING,"MultiModalApi::processLegs(\$db, \$legs, $advice_id, $country)");
        $ok = true; // All the steps on all the legs have the quotes?
        $leg_steps = [];
        foreach ($legs as $leg_id=>$leg) {
            list ($leg, $ok, $steps) = MultiModalApi::processSteps($db, $leg, $ok);
            $legs[$leg_id] = $leg;
            $leg_steps[$leg_id] = $leg_steps;
        }
        if ($ok) {
            return $this->response($legs, 200);
        }
        // Get quote
        $options = [
            "legs" => $legs,
            "leg_steps" => $leg_steps
        ];
        $options = ActivityApi::processQuotesTripMultimodalOptions(
            $db, 0, $country, $options); /* NOTE: $member_id = 0; */
        $legs = $options["legs"];            
        /*
        if (is_array($result) && isset($result["code"]) && $result["code"]==0 && isset($result["data"])) {
            $data = $result["data"];
            error_log(json_encode($data));
            foreach ($data as $leg_id=>$quote) {
                $leg = $legs[$leg_id];
                if (isset($quote['total']) && $quote['total']>0) {
                    $leg['fare_raw'] = $quote['total'];
                }
                $ok = true;
                list ($leg, $ok, $steps) = MultiModalApi::processSteps($db, $leg, $ok);
                if ($ok) {
                    $legs[$leg_id] = $leg;
                } else {
                    error_log('Failed to process steps for leg #'.$leg_id);
                }
            } 
            return $this->response($legs, 200);
        }
        */
        return $this->response($legs, 200);
        /*
        return $this->response(
            array(
                'error' => isset($result["error"])?$result["error"]:"MyTrasnport.sg service call failed"
            ), 500);*/
    }

    public static function getPolyline($id) {
        global $savvyext;
        $httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
        $oauth2_url = $savvyext->cfgReadChar('system.oauth2_url');
        $url = $oauth2_url."polyline/" . $id;
        $opts = array(
            'http' => array(
                'method' => "GET",
                'timeout' => 60, /* 1 minute */
                'header'  =>
                    "Content-Type: application/x-www-form-urlencoded\r\n" .
                    "Accept: application/json\r\n" .
                    "Authorization: Server-Token ${httpAuthToken}\r\n",
            ),
            "ssl" => array(
                "verify_peer"=>false,
                "verify_peer_name"=>false,
            )
        );
        $context = stream_context_create($opts);
        $body = file_get_contents($url, false, $context);
        $geocoded = json_decode($body,true);
        
        //var_dump($http_response_header);
        //var_dump($body);
        return $geocoded;
    }
}
