'use strict'

// Implementation of chrome.i18n.getMessage
// https://developer.chrome.com/extensions/i18n#method-getMessage
//
// Does not implement predefined messages:
// https://developer.chrome.com/extensions/i18n#overview-predefined

const { potentiallyRemoteRequire } = require('@electron/internal/renderer/remote')
const ipcRenderer = require('@electron/internal/renderer/ipc-renderer-internal')
const fs = potentiallyRemoteRequire('fs')
const path = potentiallyRemoteRequire('path')

let metadata

const getExtensionMetadata = (extensionId) => {
  if (!metadata) {
    metadata = ipcRenderer.sendSync('CHROME_I18N_MANIFEST', extensionId)
  }
  return metadata
}

const getMessagesPath = (extensionId, language) => {
  const metadata = getExtensionMetadata(extensionId)
  const localesDirectory = path.join(metadata.srcDirectory, '_locales')
  try {
    const filename = path.join(localesDirectory, language, 'messages.json')
    fs.accessSync(filename, fs.constants.R_OK)
    return filename
  } catch (err) {
    const defaultLocale = metadata.default_locale || 'en'
    return path.join(localesDirectory, defaultLocale, 'messages.json')
  }
}

const getMessages = (extensionId, language) => {
  try {
    const messagesPath = getMessagesPath(extensionId, language)
    return JSON.parse(fs.readFileSync(messagesPath)) || {}
  } catch (error) {
    return {}
  }
}

const getLanguage = () => {
  return navigator.language.replace(/-.*$/, '').toLowerCase()
}

const replaceNumberedSubstitutions = (message, substitutions) => {
  return message.replace(/\$(\d+)/, (_, number) => {
    const index = parseInt(number, 10) - 1
    return substitutions[index] || ''
  })
}

const replacePlaceholders = (message, placeholders, substitutions) => {
  if (typeof substitutions === 'string') {
    substitutions = [substitutions]
  }
  if (!Array.isArray(substitutions)) {
    substitutions = []
  }

  if (placeholders) {
    Object.keys(placeholders).forEach((name) => {
      let { content } = placeholders[name]
      content = replaceNumberedSubstitutions(content, substitutions)
      message = message.replace(new RegExp(`\\$${name}\\$`, 'gi'), content)
    })
  }

  return replaceNumberedSubstitutions(message, substitutions)
}

const getMessage = (extensionId, messageName, substitutions) => {
  const messages = getMessages(extensionId, getLanguage())
  if (messages.hasOwnProperty(messageName)) {
    const { message, placeholders } = messages[messageName]
    return replacePlaceholders(message, placeholders, substitutions)
  }
}

exports.setup = (extensionId) => {
  return {
    getMessage (messageName, substitutions) {
      return getMessage(extensionId, messageName, substitutions)
    }
  }
}
