/**
 * Dependencies
 */
const base64url = require('base64url')
const JWA = require('./JWA')

/**
 * JWS
 */
class JWS {

  /**
   * decode
   *
   * @description
   * Decode a JSON Web Token
   *
   * @param {string} token
   * @param {CryptoKey} key
   *
   * @returns {Promise}
   */
  static decode (token, key) {
    let header, payload, algorithm, signature, data

    try {
      let components = JWS.extractComponents(token)
      header = JSON.parse(base64url.decode(components[0]))
      payload = JSON.parse(base64url.decode(components[0]))
      algorithm = header.alg
      signature = components[2]
      data = components.slice(0,2).join('.')
    } catch (error) {
      return Promise.reject(error)
    }

    return JWA.verify(algorithm, key, signature, data).then(verified => {
      let jws = null

      if (verified) {
        let extendedJWS = this
        jws = new extendedJWS(header, payload, signature)
      }

      return jws
    })
  }

  /**
   * encode
   *
   * @description
   * Encode a JSON Web Token
   *
   * @param {Object} header
   * @param {Object} payload
   * @param {CryptoKey} key
   *
   * @returns {Promise}
   */
  static encode (header, payload, key) {
    let jws = new JWS(header, payload)
    return jws.encode(key)
  }

  /**
   * sign
   *
   * @description
   * Encode a JWT instance
   *
   * @param {Object} token
   * @returns {Promise}
   */
  static sign (token) {
    let payload = base64url(JSON.stringify(token.payload))

    // compact serialization
    if (token.serialization === 'compact') {
      let {key, header: {alg}} = token
      let header = base64url(JSON.stringify(token.header))
      let data = `${header}.${payload}`

      return JWA.sign(alg, key, data).then(signature => `${data}.${signature}`)
    }

    // JSON serialization
    if (token.serialization === 'json') {

    }

    // Flattened serialization
    if (token.serialization === 'flattened') {

    }

    throw new DataError('Unsupported serialization')
  }
}

/**
 * Export
 */
module.exports = JWS

@@ -118,1160 +118,8 @@
  %7B%0A%0A
-  /**%0A   * decode%0A   *%0A   * @description%0A   * Decode a JSON Web Token%0A   *%0A   * @param %7Bstring%7D token%0A   * @param %7BCryptoKey%7D key%0A   *%0A   * @returns %7BPromise%7D%0A   */%0A  static decode (token, key) %7B%0A    let header, payload, algorithm, signature, data%0A%0A    try %7B%0A      let components = JWS.extractComponents(token)%0A      header = JSON.parse(base64url.decode(components%5B0%5D))%0A      payload = JSON.parse(base64url.decode(components%5B0%5D))%0A      algorithm = header.alg%0A      signature = components%5B2%5D%0A      data = components.slice(0,2).join('.')%0A    %7D catch (error) %7B%0A      return Promise.reject(error)%0A    %7D%0A%0A    return JWA.verify(algorithm, key, signature, data).then(verified =%3E %7B%0A      let jws = null%0A%0A      if (verified) %7B%0A        let extendedJWS = this%0A        jws = new extendedJWS(header, payload, signature)%0A      %7D%0A%0A      return jws%0A    %7D)%0A  %7D%0A%0A  /**%0A   * encode%0A   *%0A   * @description%0A   * Encode a JSON Web Token%0A   *%0A   * @param %7BObject%7D header%0A   * @param %7BObject%7D payload%0A   * @param %7BCryptoKey%7D key%0A   *%0A   * @returns %7BPromise%7D%0A   */%0A  static encode (header, payload, key) %7B%0A    let jws = new JWS(header, payload)%0A    return jws.encode(key)%0A  %7D%0A%0A
   /*
@@ -130,16 +130,16 @@
  * sign%0A
+
    *%0A   
@@ -784,24 +784,24 @@
 ) %7B%0A%0A    %7D%0A%0A
-
     throw ne
@@ -844,16 +844,547 @@
 on')%0A  %7D
+%0A%0A  /**%0A   * verify%0A   */%0A  static verify (jwt) %7B%0A    // multiple signatures%0A    if (jwt.signatures) %7B%0A      // ...%0A    %7D%0A%0A    // one signature%0A    if (jwt.signature) %7B%0A      let header = base64url(JSON.stringify(jwt.header))%0A      let payload = base64url(JSON.stringify(jwt.payload))%0A      let data = %60$%7Bheader%7D.$%7Bpayload%7D%60%0A      let %7Bkey, signature, header: %7Balg%7D%7D = jwt%0A%0A      return JWA.verify(alg, key, signature, data)%0A    %7D%0A%0A    // no signatures to verify%0A    return Promise.reject(new DataError('Missing signature(s)'))%0A  %7D
 %0A%7D%0A%0A/**%0A

verify method (compact serialization)