import { activityPub } from '../ActivityPub'
import gql from 'graphql-tag'
import { createSignature } from '../security'
import request from 'request'
import CONFIG from './../../config'
const debug = require('debug')('ea:utils')

export function extractNameFromId(uri) {
  const urlObject = new URL(uri)
  const pathname = urlObject.pathname
  const splitted = pathname.split('/')

  return splitted[splitted.indexOf('users') + 1]
}

export function extractIdFromActivityId(uri) {
  const urlObject = new URL(uri)
  const pathname = urlObject.pathname
  const splitted = pathname.split('/')

  return splitted[splitted.indexOf('status') + 1]
}
export function constructIdFromName(name, fromDomain = activityPub.endpoint) {
  return `${fromDomain}/activitypub/users/${name}`
}

export function extractDomainFromUrl(url) {
  return new URL(url).host
}

export function throwErrorIfApolloErrorOccurred(result) {
  if (result.error && (result.error.message || result.error.errors)) {
    throw new Error(
      `${result.error.message ? result.error.message : result.error.errors[0].message}`,
    )
  }
}

export function signAndSend(activity, fromName, targetDomain, url) {
  // fix for development: replace with http
  url = url.indexOf('localhost') > -1 ? url.replace('https', 'http') : url
  debug(`passhprase = ${CONFIG.PRIVATE_KEY_PASSPHRASE}`)
  return new Promise((resolve, reject) => {
    debug('inside signAndSend')
    // get the private key
    activityPub.dataSource.client
      .query({
        query: gql`
          query {
              User(slug: "${fromName}") {
                  privateKey
              }
          }
      `,
      })
      .then(result => {
        if (result.error) {
          reject(result.error)
        } else {
          // add security context
          const parsedActivity = JSON.parse(activity)
          if (Array.isArray(parsedActivity['@context'])) {
            parsedActivity['@context'].push('https://w3id.org/security/v1')
          } else {
            const context = [parsedActivity['@context']]
            context.push('https://w3id.org/security/v1')
            parsedActivity['@context'] = context
          }

          // deduplicate context strings
          parsedActivity['@context'] = [...new Set(parsedActivity['@context'])]
          const privateKey = result.data.User[0].privateKey
          const date = new Date().toUTCString()

          debug(`url = ${url}`)
          request(
            {
              url: url,
              headers: {
                Host: targetDomain,
                Date: date,
                Signature: createSignature({
                  privateKey,
                  keyId: `${activityPub.endpoint}/activitypub/users/${fromName}#main-key`,
                  url,
                  headers: {
                    Host: targetDomain,
                    Date: date,
                    'Content-Type': 'application/activity+json',
                  },
                }),
                'Content-Type': 'application/activity+json',
              },
              method: 'POST',
              body: JSON.stringify(parsedActivity),
            },
            (error, response) => {
              if (error) {
                debug(`Error = ${JSON.stringify(error, null, 2)}`)
                reject(error)
              } else {
                debug('Response Headers:', JSON.stringify(response.headers, null, 2))
                debug('Response Body:', JSON.stringify(response.body, null, 2))
                resolve()
              }
            },
          )
        }
      })
  })
}
