/**
* @flow
* This file is generated automatically, run npm run build to re-generate.
**/

import type { Cookie } from './cookie';
import type Driver from './driver';
import addDebugging from './add-debugging';
import { parse } from 'url';
import BaseClass from './base-class';

/*
 * Validate the cookie data
 *
 * @private
 */
function validateCookie(cookie: Cookie, completed: boolean = false) {
  if (completed) {
    if (!cookie.name) {
      throw new Error('A cookie "name" is required.');
    }
    if (!cookie.value) {
      throw new Error('a cookie "value" is required.');
    }
  }

  if (!cookie.path) {
    cookie.path = '/';
  }

  // localhost is a special case, the domain must be ""
  if (cookie.domain === 'localhost') cookie.domain = '';

  return cookie;
}

/*
 * Managing cookie-storage
 */
class CookieStorage extends BaseClass {
  constructor(driver: Driver) {
    super(driver, '/cookie');
  }

  /*
   * Retrieve all cookies visible to the current page.
   */
  getCookies(): Array<Cookie> {
    return this.requestJSON('GET', '');
  }

  /*
   * Retrieve all cookie names visible to the current page.
   */
  getKeys(): Array<string> {
    const cookies = this.requestJSON('GET', '');
    return cookies.map(cookie => cookie.name);
  }

  /*
   * Retrieve a specific cookie by name that is visible to the current page.
   */
  getCookie(name: string): Cookie | void {
    let cookies = this.getCookies();
    cookies = cookies.filter(cookie => {
      return cookie.name == name;
    });
    return cookies.length ? cookies[0] : undefined;
  }

  /*
   * Set a cookie that is visible to the current page.
   */
  setCookie(cookie: Cookie): void {
    validateCookie(cookie, true);

    if (cookie.domain != null) {
      this.requestJSON('POST', '', { cookie });
    } else {
      const base = this.driver.activeWindow.getUrl();
      const hostname = parse(base).hostname;
      if (hostname == null) {
        throw new Error('The hostname should never be undefined. This should never happen.');
      }
      cookie.domain = hostname;
      validateCookie(cookie, true);
      this.requestJSON('POST', '', { cookie });
    }
  }

  /*
   * Delete the cookie with the given name.
   */
  removeCookie(name: string): void {
    this.requestJSON('DELETE', '/' + name);
  }

  /*
   * Delete all cookies visible to the current page.
   */
  clear(): void {
    this.requestJSON('DELETE', '');
  }

  /*
   * Get the number of items in the storage
   */
  getSize(): number {
    const cookies = this.getCookies();
    return cookies.length;
  }
}
addDebugging(CookieStorage);
export default CookieStorage;