(function() {
  var Command, Install, Login, Stars, _, config, request, tree, yargs;

  _ = require('underscore-plus');

  yargs = require('yargs');

  Command = require('./command');

  config = require('./apm');

  Install = require('./install');

  Login = require('./login');

  request = require('./request');

  tree = require('./tree');

  module.exports = Stars = (function() {
    class Stars extends Command {
      parseOptions(argv) {
        var options;
        options = yargs(argv).wrap(100);
        options.usage("\nUsage: apm stars\n       apm stars --install\n       apm stars --user thedaniel\n       apm stars --themes\n\nList or install starred Atom packages and themes.");
        options.alias('h', 'help').describe('help', 'Print this usage message');
        options.alias('i', 'install').boolean('install').describe('install', 'Install the starred packages');
        options.alias('t', 'themes').boolean('themes').describe('themes', 'Only list themes');
        options.alias('u', 'user').string('user').describe('user', 'GitHub username to show starred packages for');
        return options.boolean('json').describe('json', 'Output packages as a JSON array');
      }

      getStarredPackages(user, atomVersion, callback) {
        var requestSettings;
        requestSettings = {
          json: true
        };
        if (atomVersion) {
          requestSettings.qs = {
            engine: atomVersion
          };
        }
        if (user) {
          requestSettings.url = `${config.getAtomApiUrl()}/users/${user}/stars`;
          return this.requestStarredPackages(requestSettings, callback);
        } else {
          requestSettings.url = `${config.getAtomApiUrl()}/stars`;
          return Login.getTokenOrLogin((error, token) => {
            if (error != null) {
              return callback(error);
            }
            requestSettings.headers = {
              authorization: token
            };
            return this.requestStarredPackages(requestSettings, callback);
          });
        }
      }

      requestStarredPackages(requestSettings, callback) {
        return request.get(requestSettings, function(error, response, body = []) {
          var message, packages;
          if (error != null) {
            return callback(error);
          } else if (response.statusCode === 200) {
            packages = body.filter(function(pack) {
              var ref;
              return (pack != null ? (ref = pack.releases) != null ? ref.latest : void 0 : void 0) != null;
            });
            packages = packages.map(function({readme, metadata, downloads, stargazers_count}) {
              return _.extend({}, metadata, {readme, downloads, stargazers_count});
            });
            packages = _.sortBy(packages, 'name');
            return callback(null, packages);
          } else {
            message = request.getErrorMessage(response, body);
            return callback(`Requesting packages failed: ${message}`);
          }
        });
      }

      installPackages(packages, callback) {
        var commandArgs;
        if (packages.length === 0) {
          return callback();
        }
        commandArgs = packages.map(function({name}) {
          return name;
        });
        return new Install().run({commandArgs, callback});
      }

      logPackagesAsJson(packages, callback) {
        console.log(JSON.stringify(packages));
        return callback();
      }

      logPackagesAsText(user, packagesAreThemes, packages, callback) {
        var label, userLabel;
        userLabel = user != null ? user : 'you';
        if (packagesAreThemes) {
          label = `Themes starred by ${userLabel}`;
        } else {
          label = `Packages starred by ${userLabel}`;
        }
        console.log(`${label.cyan} (${packages.length})`);
        tree(packages, function({name, version, description, downloads, stargazers_count}) {
          label = name.yellow;
          if (process.platform === 'darwin') {
            label = `\u2B50  ${label}`;
          }
          if (description) {
            label += ` ${description.replace(/\s+/g, ' ')}`;
          }
          if (downloads >= 0 && stargazers_count >= 0) {
            label += ` (${_.pluralize(downloads, 'download')}, ${_.pluralize(stargazers_count, 'star')})`.grey;
          }
          return label;
        });
        console.log();
        console.log(`Use \`apm stars --install\` to install them all or visit ${'http://atom.io/packages'.underline} to read more about them.`);
        console.log();
        return callback();
      }

      run(options) {
        var callback, ref, user;
        ({callback} = options);
        options = this.parseOptions(options.commandArgs);
        user = (ref = options.argv.user) != null ? ref.toString().trim() : void 0;
        return this.getStarredPackages(user, options.argv.compatible, (error, packages) => {
          if (error != null) {
            return callback(error);
          }
          if (options.argv.themes) {
            packages = packages.filter(function({theme}) {
              return theme;
            });
          }
          if (options.argv.install) {
            return this.installPackages(packages, callback);
          } else if (options.argv.json) {
            return this.logPackagesAsJson(packages, callback);
          } else {
            return this.logPackagesAsText(user, options.argv.themes, packages, callback);
          }
        });
      }

    };

    Stars.commandNames = ['stars', 'starred'];

    return Stars;

  }).call(this);

}).call(this);
