import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
import {
  SendingQuery,
  PeerResponse,
  FinalPeer,
  QueryError,
  Provider,
  Value,
  AddingPeer,
  DialingPeer
} from './response-types.js';
import { Multiaddr } from 'multiaddr';
export const mapEvent = event => {
  if (event.Type === SendingQuery) {
    return {
      to: event.ID,
      name: 'SENDING_QUERY',
      type: event.Type
    };
  }
  if (event.Type === PeerResponse) {
    return {
      from: event.ID,
      name: 'PEER_RESPONSE',
      type: event.Type,
      messageType: 0,
      messageName: 'PUT_VALUE',
      closer: (event.Responses || []).map(({ID, Addrs}) => ({
        id: ID,
        multiaddrs: Addrs.map(addr => new Multiaddr(addr))
      })),
      providers: (event.Responses || []).map(({ID, Addrs}) => ({
        id: ID,
        multiaddrs: Addrs.map(addr => new Multiaddr(addr))
      }))
    };
  }
  if (event.Type === FinalPeer) {
    let peer = {
      id: event.ID,
      multiaddrs: []
    };
    if (event.Responses && event.Responses.length) {
      peer = {
        id: event.Responses[0].ID,
        multiaddrs: event.Responses[0].Addrs.map(addr => new Multiaddr(addr))
      };
    }
    return {
      from: event.ID,
      name: 'FINAL_PEER',
      type: event.Type,
      peer
    };
  }
  if (event.Type === QueryError) {
    return {
      from: event.ID,
      name: 'QUERY_ERROR',
      type: event.Type,
      error: new Error(event.Extra)
    };
  }
  if (event.Type === Provider) {
    return {
      from: event.ID,
      name: 'PROVIDER',
      type: event.Type,
      providers: event.Responses.map(({ID, Addrs}) => ({
        id: ID,
        multiaddrs: Addrs.map(addr => new Multiaddr(addr))
      }))
    };
  }
  if (event.Type === Value) {
    return {
      from: event.ID,
      name: 'VALUE',
      type: event.Type,
      value: uint8ArrayFromString(event.Extra, 'base64pad')
    };
  }
  if (event.Type === AddingPeer) {
    const peers = event.Responses.map(({ID}) => ID);
    if (!peers.length) {
      throw new Error('No peer found');
    }
    return {
      name: 'ADDING_PEER',
      type: event.Type,
      peer: peers[0]
    };
  }
  if (event.Type === DialingPeer) {
    return {
      name: 'DIALING_PEER',
      type: event.Type,
      peer: event.ID
    };
  }
  throw new Error('Unknown DHT event type');
};