// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

require('es6-shim');

var _ = require('lodash');
var uuid = require('uuid');

var $ = require('../util/jquery');
var defineClass = require('../util/define-class');

var debug = require('../debug');

var getTripLength = require('./get-trip-length');
var tripComparator = require('./trip-comparator');

var TripManager = defineClass({
  statics: {
    getTripLength: getTripLength
  },

  publics: {
    /**
     * Sets the active trip to the given trip ID after it is available.
     */
    watchForTrip: function(tripId) {
      this.awaitedTripId = tripId;
    },

    getMessageData: function() {
      return this.activeTrip && this.activeTrip.messages;
    },

    getDestinationData: function() {
      return this.activeTrip && this.activeTrip.destinations;
    },

    getActiveTripId: function() {
      return this.activeTripId;
    },

    getActiveTripOwner: function() {
      return this.activeTrip && this.activeTrip.owner;
    },

    setActiveTripId: function(tripId) {
      var old = this.activeTripId;
      this.activeTripId = tripId;
      this.sbw.put(['user', 'tripMetadata', tripId, 'latestSwitch'],
        Date.now());

      if (old !== tripId) {
        this.activeTrip = null;
        this.activeTripOwner = null;
      }
    },

    hasValidUpstream: function() {
      return this.upstreamTripId && this.upstreamTripId === this.activeTripId;
    },

    getTripKey: function() {
      return ['trips', this.upstreamTripId].concat(_.flattenDeep(arguments));
    },

    getDestinationsKey: function() {
      return this.getTripKey('destinations', arguments);
    },

    getMessagesKey: function() {
      return this.getTripKey('messages', arguments);
    },

    /**
     * This should be called whenever the upstream should be considered ready to
     * receive updates from local, i.e. after refreshing from remote or before
     * pushing from local.
     */
    setUpstream: function() {
      this.upstreamTripId = this.activeTripId;
    },

    processTrips: function(userTripMetadata, trips) {
      var self = this;

      var trip;

      if (this.awaitedTripId) {
        this.setActiveTripId(this.awaitedTripId);
        delete this.awaitedTripId;

        /* Override latestSwitch this frame. (Subsequently syncbase will be up
         * to date.) */
        if (!userTripMetadata) {
          userTripMetadata = {};
        }
        var activeTripMd = userTripMetadata[this.activeTripId];
        if (!activeTripMd) {
          activeTripMd = userTripMetadata[this.activeTripId] = {};
        }
        activeTripMd.latestSwitch = Date.now();
      }

      if (this.activeTripId) {
        trip = trips && trips[this.activeTripId];
        if (!trip) {
          debug.log('Last active trip ' + this.activeTripId +
            ' is no longer present.');
        } else {
          var defaultId = this.getDefaultTrip(userTripMetadata, trips);
          if (defaultId && defaultId !== this.activeTripId &&
              trips[defaultId]) {
            if (this.isNascent(trip)) {
              this.deleteTrip(this.activeTripId);
              debug.log('Replacing nascent trip ' + this.activeTripId +
                ' with established trip ' + defaultId);
            } else {
              /* TODO(rosswang): for now, sync trip changes. This behavior may
               * change. */
              debug.log('Replacing active trip ' + this.activeTripId +
                ' with most recent selection ' + defaultId);
            }

            this.activeTripId = defaultId;
            trip = trips[defaultId];
          }
        }
      }

      if (!trip) {
        if (trips) {
          this.activeTripId = this.getDefaultTrip(userTripMetadata, trips);
          debug.log('Setting active trip ' + this.activeTripId);
          trip = trips[this.activeTripId];
        } else {
          var tripId = this.activeTripId = uuid.v4();
          debug.log('Creating new trip ' + tripId);
          trip = {};
          this.startSyncgroupManager.then(function(sgm) {
            return sgm.syncbaseWrapper.put(['trips', tripId, 'owner'],
                sgm.identity.username)
              .catch(self.onError);
          });
        }
      }

      this.activeTrip = trip;
    }
  },

  privates: {
    deleteTrip: function(tripId) {
      this.sbw.batch(function(ops) {
        return Promise.all([
          ops.delete(['user', 'tripMetadata', tripId]),
          ops.delete(['trips', tripId])
        ]);
      });
    },

    /**
     * Given a mapping of trip IDs to trip info with metadata, pick the trip
     * that the user is most likely to care about.
     */
    getDefaultTrip: function(userTripMetadata, trips) {
      var best;

      $.each(trips, function(id, trip) {
        var md = userTripMetadata && userTripMetadata[id];
        var latestSwitch = md && md.latestSwitch;

        var candidate =
          new tripComparator.ComparableTrip(trip, id, latestSwitch);

        if (tripComparator.compareTrips(best, candidate) > 0) {
          best = candidate;
        }
      });

      return best && best.id;
    },

    isNascent: function(trip) {
      return this.getTripLength(trip) <= 1;
    }
  },

  init: function(usernamePromise, deferredSyncbaseWrapper,
      startSyncgroupManager) {
    this.usernamePromise = usernamePromise;
    this.sbw = deferredSyncbaseWrapper;
    this.startSyncgroupManager = startSyncgroupManager;
    this.joinedTrips = new Set();
  }
});

module.exports = TripManager;