<template>
  <div class="hosts-container">
    <div class="no-items" v-if="!Object.keys(services).length">No Platypush services found on the network</div>

    <div class="service" v-for="(service, id) in services" :key="id" @click="onClick(service)">
      <span class="name" v-text="service.name" />
      at
      <span class="address" v-text="service.addresses[0]" />:<span class="port" v-text="service.port" />
    </div>
  </div>
</template>

<script>
export default {
  name: "Hosts",
  data() {
    return {
      ws: null,
      wsUrl: 'ws://localhost:3080/',
      services: {},
      connRetrySeconds: 10,
      connRetryInterval: null,
    }
  },

  methods: {
    refresh() {
      if (this.ws)
        this.ws.close()

      this.ws = new WebSocket(this.wsUrl)
      this.ws.onopen = this.onOpen
      this.ws.onmessage = this.onMessage
      this.ws.onclose = this.onClose
      this.ws.onerror = this.onClose
    },

    onOpen() {
      if (this.connRetryInterval != null) {
        clearInterval(this.connRetryInterval)
        this.connRetryInterval = null
      }

      console.log(`Connected to web socket on ${this.wsUrl}`)
      this.ws.send('sync')
    },

    onClose() {
      console.warn(`The websocket connection went down: retrying in ${this.connRetrySeconds} seconds`)
      try {
        this.ws.close()
      } catch (e) {
        console.warn(e)
      } finally {
        this.ws = null
      }

      if (this.connRetryInterval == null)
        this.connRetryInterval = setInterval(this.refresh, this.connRetrySeconds * 1000)
    },

    onMessage(msg) {
      const service = JSON.parse(msg.data)
      this.services[service.fqdn] = service
    },

    onClick(service) {
      window.location.href = `http://${service.addresses[0]}:${service.port}/`
    },
  },

  mounted() {
    this.refresh()
  },
}
</script>

<style lang="scss" scoped>
@import "../style/common";

.hosts-container {
  width: 50%;
  height: max-content;
  min-width: 17.5em;
  max-width: 27.5em;
  background: $panel-bg;
  margin-top: 3em;
  box-shadow: 1px 1px 2px 2px #bbb;
  border-radius: 1.5em;

  .no-items {
    text-align: center;
    padding: 2em 1em;
  }

  .service {
    padding: 1em .5em;
    border-bottom: 1px solid #ccc;
    cursor: pointer;

    &:first-child {
      border-radius: 1.5em 1.5em 0 0;
    }

    &:last-child {
      border-radius: 0 0 1.5em 1.5em;
    }

    &:hover {
      background: $hover-bg;
    }

    .name {
      font-weight: bold;
    }
  }
}
</style>
