// 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 vanadium = require('vanadium');

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

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

var SyncgroupManager = require('./syncgroup-manager');
var InvitationManager = require('./invitation-manager');

var DeferredSbWrapper = require('./sync-util/deferred-sb-wrapper');
var DestinationSync = require('./sync-util/destination-sync');
var DeviceSync = require('./sync-util/device-sync');
var MessageSync = require('./sync-util/message-sync');
var TripManager = require('./sync-util/trip-manager');

var vdlTravel = require('../ifc');

var TravelSync = defineClass({
  /* Schema note: although we don't support merging destination list structure
   * changes, we use indirection in the destination list so that we don't have
   * to move multiple keys on random insertion or deletion and can still support
   * parallel destination edits. */
  publics: {
    bindDestinations: function(destinations) {
      this.destinationSync.bindDestinations(destinations);
    },

    message: function(messageContent) {
      this.messageSync.message(messageContent);
    },

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

    getActiveTripOwner: function() {
      return this.tripManager.getActiveTripOwner();
    },

    setActiveTripId: function(tripId) {
      this.tripManager.setActiveTripId(tripId);
    },

    getData: function() {
      return this.sbw.getData();
    },

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

    joinTripSyncGroup: function(owner, tripId) {
      return this.tripManager.joinTripSyncGroup(owner, tripId);
    },

    getRelatedDevices: function(direction) {
      return this.deviceSync.getRelatedDevices(direction);
    },

    getUnconnectedCastTargets: function() {
      return this.deviceSync.getUnconnectedCastTargets();
    },

    getPossibleCastTargets: function() {
      return this.deviceSync.getPossibleCastTargets();
    },

    relateDevice: function(owner, device, relativePosition) {
      return this.deviceSync.relate(owner, device, relativePosition);
    },

    cast: function(owner, device, spec) {
      var self = this;
      return this.clientPromise(naming.rpcMount(owner, device))
        .then(function(s) {
          return self.vanadiumWrapperPromise.then(function(vanadiumWrapper) {
            return s.cast(vanadiumWrapper.context(),
              new vdlTravel.CastSpec(spec));
          });
        });
    }
  },

  privates: {
    processUpdates: function(data) {
      this.deviceSync.processDevices(data.devices);

      this.tripManager.processTrips(data.user && data.user.tripMetadata,
        data.trips);

      this.messageSync.processMessages(this.tripManager.getMessageData());
      this.destinationSync.processDestinations(
        this.tripManager.getDestinationData());

      this.tripManager.setUpstream();
    },

    getRpcEndpoint: function(args) {
      return vanadium.naming.join(args.mountNames.device, 'rpc');
    },

    serve: function(args) {
      var self = this;
      var vanadiumWrapper = args.vanadiumWrapper;

      this.status.rpc = 'starting';
      return vanadiumWrapper.server(args.mountNames.rpc, this.server)
        .then(function(server) {
          self.status.rpc = 'ready';
          return server;
        }, function(err) {
          self.status.rpc = 'failed';
          throw err;
        });
    },

    connectSyncbase: function(args) {
      var self = this;
      var vanadiumWrapper = args.vanadiumWrapper;

      this.status.syncbase = 'starting';
      return vanadiumWrapper
        .syncbase(this.syncbaseName)
        .then(function(syncbase) {
          self.status.syncbase = 'ready';
          return syncbase;
        }, function(err) {
          self.status.syncbase = 'failed';
          throw err;
        });
    },

    createSyncgroupManager: function(args, syncbase) {
      var gm = new SyncgroupManager(args.identity, args.vanadiumWrapper,
        syncbase, args.mountNames);
      gm.onError.add(this.onError);

      return gm;
    },

    createPrimarySyncGroup: function(syncgroupManager) {
      var self = this;

      this.status.userSyncGroup = 'creating';
      return syncgroupManager.createSyncGroup('user', [[]],
        [syncgroupManager.identity.username])
        .then(function(sg) {
          self.status.userSyncGroup = 'created';
          return sg;
        }, function(err) {
          self.status.userSyncGroup = 'failed';
          throw err;
        });
    },

    handleCast: function(ctx, serverCall, spec) {
      console.debug('Cast target for ' + spec.panelName);
    },

    clientPromise: function(endpoint) {
      var clientPromise = this.clients[endpoint];
      if (!clientPromise) {
        clientPromise = this.clients[endpoint] = this.vanadiumWrapperPromise
          .then(function(vanadiumWrapper) {
            return vanadiumWrapper.client(endpoint);
          });
      }

      return clientPromise;
    }

    /*
    updateRemoteBounds: function(name, bounds) {
      var self = this;
      var client = this.clients[name];
      if (!client) {
        client = this.clients[name] = this.prereqs.then(function(args) {
          return args.vanadiumWrapper.client(name);
        });
      }

      var sw = bounds.getSouthWest();
      var ne = bounds.getNorthEast();

      return client.then(function(s) {
        return self.prereqs.then(function(args) {
          var vBounds = new vdlTravel.LatLngBounds({
            southWest: new vdlTravel.LatLng({
              lat: sw.lat(),
              lng: sw.lng()
            }),
            northEast: new vdlTravel.LatLng({
              lat: ne.lat(),
              lng: ne.lng()
            })
          });

          return s.setBounds(args.vanadiumWrapper.context(), vBounds);
        });
      });
    },

    rpcSetBounds: function(vBounds) {
      var bounds = new this.maps.LatLngBounds(
        new this.maps.LatLng(vBounds.southWest.lat,
          vBounds.southWest.lng),
        new this.maps.LatLng(vBounds.northEast.lat,
          vBounds.northEast.lng));

      console.debug('in: ' + bounds);

      this.onSetBounds(bounds);
    }*/
  },

  constants: [ 'invitationManager', 'startup', 'status' ],
  events: {
    /**
     * @param newSize
     */
    onTruncateDestinations: '',

    /**
     * @param i
     * @param place
     */
    onPlaceChange: '',

    onError: 'memory',

    /**
     * Triggered when devices are discovered (possibly) nearby, where none were
     * present before.
     */
    onPossibleNearbyDevices: '',

    /**
     * @param messages array of {content, timestamp} pair objects.
     */
    onMessages: '',

    onStatusUpdate: ''
  },

  /**
   * @param prereqs a promise that produces { identity, mountNames,
   *  vanadiumWrapper }.
   * @mapsDependencies an object with the following keys:
   *  maps
   *  placesService
   * @syncbaseName name of the local SyncBase endpoint.
   */
  init: function(prereqs, mapsDependencies, syncbaseName) {
    var self = this;

    this.syncbaseName = syncbaseName;
    this.maps = mapsDependencies.maps;

    this.tripStatus = {};
    this.status = {};
    this.clients = {};

    this.server = new vdlTravel.Travel();
    this.server.cast = function(ctx, serverCall, spec) {
      self.handleCast(ctx, serverCall, spec);
    };
    var startRpc = prereqs.then(this.serve);
    var startSyncbase = prereqs.then(this.connectSyncbase);

    var sbw = this.sbw = new DeferredSbWrapper(startSyncbase);
    sbw.onError.add(this.onError);
    sbw.onUpdate.add(this.processUpdates);

    this.startSyncgroupManager = Promise
      .all([prereqs, startSyncbase])
      .then(function(args) {
        return self.createSyncgroupManager(args[0], args[1]);
      });
    var createPrimarySyncGroup = this.startSyncgroupManager
      .then(this.createPrimarySyncGroup);

    this.vanadiumWrapperPromise = prereqs.then(function(args) {
      return args.vanadiumWrapper;
    });
    var usernamePromise = prereqs.then(function(args) {
      return args.identity.username;
    });

    this.tripManager = new TripManager(
      usernamePromise, sbw, this.startSyncgroupManager);
    this.messageSync = new MessageSync(sbw, this.tripManager);
    this.destinationSync = new DestinationSync(
      mapsDependencies, sbw, this.tripManager);

    this.messageSync.onMessages.add(this.onMessages);

    this.deviceSync = new DeviceSync(mapsDependencies.maps,
        prereqs.then(function(args) { return args.identity; }),
        self.sbw);
    this.deviceSync.onError.add(this.onError);
    this.deviceSync.onPossibleNearbyDevices.add(this.onPossibleNearbyDevices);

    this.startup = Promise.all([
        startRpc,
        startSyncbase,
        this.startSyncgroupManager,
        createPrimarySyncGroup
      ]).then(function(values) {
        return {
          server: values[0],
          syncbase: values[1],
          groupManager: values[2]
        };
      });

    this.invitationManager = new InvitationManager(this.startSyncgroupManager);
    this.invitationManager.onError.add(this.onError);
  }
});

module.exports = TravelSync;
