"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.setPreference = exports.getPreference = exports.clearPreference = exports.purgePreferences = exports.userDataDir = void 0;

var _debug = _interopRequireDefault(require("debug"));

var _path = require("path");

var _store = _interopRequireDefault(require("../models/store"));

var _home = _interopRequireDefault(require("../util/home"));

var _capabilities = require("../core/capabilities");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/*
 * Copyright 2017-18 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var __awaiter = void 0 && (void 0).__awaiter || function (thisArg, _arguments, P, generator) {
  function adopt(value) {
    return value instanceof P ? value : new P(function (resolve) {
      resolve(value);
    });
  }

  return new (P || (P = Promise))(function (resolve, reject) {
    function fulfilled(value) {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    }

    function rejected(value) {
      try {
        step(generator["throw"](value));
      } catch (e) {
        reject(e);
      }
    }

    function step(result) {
      result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
    }

    step((generator = generator.apply(thisArg, _arguments || [])).next());
  });
};

const debug = (0, _debug.default)('core/userdata');
/**
 * Get the userdata directory
 *
 */

const userDataDir = () => {
  if ((0, _capabilities.inBrowser)()) {
    throw new Error('Unsupported operation');
  } else {
    // headless
    const name = '@kui-shell/settings';

    switch (process.platform) {
      case 'darwin':
        return (0, _path.join)(process.env.HOME, 'Library', 'Application Support', name);

      case 'linux':
        {
          const home = process.env.XDG_CONFIG_HOME || (0, _home.default)('~/.config');
          return (0, _path.join)(home, name);
        }

      case 'win32':
        return (0, _path.join)(process.env.APPDATA, name);
    }
  }
};
/** filepath to persisted preference model */


exports.userDataDir = userDataDir;

const preferencesFilepath = () => (0, _path.join)(userDataDir(), 'prefs.json');
/**
 * Sync the preferences to disk
 *
 * @return passes through the preference model
 *
 */


const fsyncPreferences = prefs => __awaiter(void 0, void 0, void 0, function* () {
  if ((0, _capabilities.inBrowser)()) {
    (0, _store.default)().setItem('kui.userprefs', JSON.stringify(prefs));
  } else {
    const {
      mkdirp,
      writeFile
    } = yield Promise.resolve().then(() => require('fs-extra'));
    yield mkdirp(userDataDir());
    yield writeFile(preferencesFilepath(), JSON.stringify(prefs));
  }

  return prefs;
});

function readFile(filepath) {
  return __awaiter(this, void 0, void 0, function* () {
    const {
      readFile
    } = yield Promise.resolve().then(() => require('fs'));
    return new Promise((resolve, reject) => {
      readFile(filepath, (err, data) => {
        if (err) {
          reject(err);
        } else {
          resolve(data.toString());
        }
      });
    });
  });
}
/**
 * Read the preference model
 *
 */


const preferences = () => __awaiter(void 0, void 0, void 0, function* () {
  if ((0, _capabilities.inBrowser)()) {
    debug('reading preferences from browser localStorage');
    const prefs = (0, _store.default)().getItem('kui.userprefs');

    if (!prefs) {
      return {};
    } else {
      try {
        return JSON.parse(prefs);
      } catch (err) {
        debug('error parsing preference model', prefs);
        console.error('error parsing preference model', err);
        return {};
      }
    }
  }

  try {
    const filepath = preferencesFilepath();
    debug('reading persisted preference model', filepath);
    const raw = yield readFile(filepath);

    try {
      return JSON.parse(raw);
    } catch (err) {
      debug('error parsing preference model', raw);
      console.error('error parsing preference model', err);
      return {};
    }
  } catch (err) {
    if (err.code === 'ENOENT') {
      return fsyncPreferences({});
    } else {
      throw err;
    }
  }
});
/**
 * Purge the preference model
 *
 */


const purgePreferences = () => __awaiter(void 0, void 0, void 0, function* () {
  debug('purgePreferences');

  if ((0, _capabilities.inBrowser)()) {
    (0, _store.default)().removeItem('kui.userprefs');
  } else {
    const {
      unlink
    } = yield Promise.resolve().then(() => require('fs-extra'));
    yield unlink(preferencesFilepath());
  }
});
/**
 * Remove the preference associated with the given key
 *
 * @return the prior value
 *
 */


exports.purgePreferences = purgePreferences;

const clearPreference = key => __awaiter(void 0, void 0, void 0, function* () {
  debug('clearPreference', key);
  const prefs = yield preferences();
  const value = prefs[key];
  delete prefs[key];
  yield fsyncPreferences(prefs);
  return value;
});
/**
 * Get a persisted preference
 *
 * @return the preference value
 *
 */


exports.clearPreference = clearPreference;

const getPreference = key => __awaiter(void 0, void 0, void 0, function* () {
  const prefs = yield preferences();
  const value = prefs[key];
  debug('getPreference', key, value);
  return value;
});
/**
 * Set a persisted preference
 *
 * @return the preference value
 *
 */


exports.getPreference = getPreference;

const setPreference = (key, value) => __awaiter(void 0, void 0, void 0, function* () {
  debug('setPreference', key, value);
  const prefs = yield preferences();
  prefs[key] = value;
  yield fsyncPreferences(prefs);
  return value;
});

exports.setPreference = setPreference;