(function() {
  var $, CommandLogger, NotificationIssue, StackTraceParser, UserUtilities, fs, path;

  $ = require('jquery');

  fs = require('fs');

  path = require('path');

  StackTraceParser = require('stacktrace-parser');

  CommandLogger = require('./command-logger');

  UserUtilities = require('./user-utilities');

  module.exports = NotificationIssue = (function() {
    function NotificationIssue(notification) {
      this.notification = notification;
    }

    NotificationIssue.prototype.findSimilarIssues = function() {
      var query, repo, repoUrl, url;
      url = "https://api.github.com/search/issues";
      repoUrl = this.getRepoUrl();
      if (repoUrl == null) {
        repoUrl = 'atom/atom';
      }
      repo = repoUrl.replace(/http(s)?:\/\/(\d+\.)?github.com\//gi, '');
      query = "" + (this.getIssueTitle()) + " repo:" + repo;
      return new Promise((function(_this) {
        return function(resolve, reject) {
          return $.ajax("" + url + "?q=" + (encodeURI(query)) + "&sort=created", {
            accept: 'application/vnd.github.v3+json',
            contentType: "application/json",
            success: function(data) {
              var issue, issues, _i, _len, _ref;
              if (data.items != null) {
                issues = {};
                _ref = data.items;
                for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                  issue = _ref[_i];
                  if (issue.title.indexOf(_this.getIssueTitle()) > -1 && (issues[issue.state] == null)) {
                    issues[issue.state] = issue;
                  }
                }
                if ((issues.open != null) || (issues.closed != null)) {
                  return resolve(issues);
                }
              }
              return resolve(null);
            },
            error: function() {
              return resolve(null);
            }
          });
        };
      })(this));
    };

    NotificationIssue.prototype.getIssueUrlForSystem = function() {
      return new Promise((function(_this) {
        return function(resolve, reject) {
          _this.getIssueUrl().then(function(issueUrl) {
            if (UserUtilities.getPlatform() === 'win32') {
              return $.ajax('http://git.io', {
                type: 'POST',
                data: {
                  url: issueUrl
                },
                success: function(data, status, xhr) {
                  return resolve(xhr.getResponseHeader('Location'));
                },
                error: function() {
                  return resolve(issueUrl);
                }
              });
            } else {
              return resolve(issueUrl);
            }
          });
        };
      })(this));
    };

    NotificationIssue.prototype.getIssueUrl = function() {
      return this.getIssueBody().then((function(_this) {
        return function(issueBody) {
          var repoUrl;
          repoUrl = _this.getRepoUrl();
          if (repoUrl == null) {
            repoUrl = 'https://github.com/atom/atom';
          }
          return "" + repoUrl + "/issues/new?title=" + (_this.encodeURI(_this.getIssueTitle())) + "&body=" + (_this.encodeURI(issueBody));
        };
      })(this));
    };

    NotificationIssue.prototype.getIssueTitle = function() {
      return this.notification.getMessage();
    };

    NotificationIssue.prototype.getIssueBody = function() {
      return new Promise((function(_this) {
        return function(resolve, reject) {
          var installedPackagesPromise, systemPromise;
          if (_this.issueBody) {
            return resolve(_this.issueBody);
          }
          systemPromise = UserUtilities.getOSVersion();
          installedPackagesPromise = UserUtilities.getInstalledPackages();
          return Promise.all([systemPromise, installedPackagesPromise]).then(function(all) {
            var atomVersion, copyText, installedPackages, message, options, packageMessage, packageName, packageVersion, repoUrl, systemName, userConfig, _ref, _ref1;
            systemName = all[0], installedPackages = all[1];
            message = _this.notification.getMessage();
            options = _this.notification.getOptions();
            repoUrl = _this.getRepoUrl();
            packageName = _this.getPackageName();
            if (packageName != null) {
              packageVersion = (_ref = atom.packages.getLoadedPackage(packageName)) != null ? (_ref1 = _ref.metadata) != null ? _ref1.version : void 0 : void 0;
            }
            userConfig = UserUtilities.getConfigForPackage(packageName);
            copyText = '';
            if ((packageName != null) && (repoUrl != null)) {
              packageMessage = "[" + packageName + "](" + repoUrl + ") package, v" + packageVersion;
            } else if (packageName != null) {
              packageMessage = "'" + packageName + "' package, v" + packageVersion;
            } else {
              packageMessage = 'Atom Core';
            }
            atomVersion = atom.getVersion();
            if (atom.getLoadSettings().apiPreviewMode) {
              atomVersion += " :warning: **in 1.0 API Preview Mode** :warning:";
            }
            _this.issueBody = "[Enter steps to reproduce below:]\n\n1. ...\n2. ...\n\n**Atom Version**: " + atomVersion + "\n**System**: " + systemName + "\n**Thrown From**: " + packageMessage + "\n\n### Stack Trace\n\n" + message + "\n\n```\nAt " + options.detail + "\n\n" + options.stack + "\n```\n\n### Commands\n\n" + (CommandLogger.instance().getText()) + "\n\n### Config\n\n```json\n" + (JSON.stringify(userConfig, null, 2)) + "\n```\n\n### Installed Packages\n\n```coffee\n# User\n" + (installedPackages.user.join('\n') || 'No installed packages') + "\n\n# Dev\n" + (installedPackages.dev.join('\n') || 'No dev packages') + "\n```\n\n" + copyText;
            return resolve(_this.issueBody);
          });
        };
      })(this));
    };

    NotificationIssue.prototype.encodeURI = function(str) {
      str = encodeURI(str);
      return str.replace(/#/g, '%23').replace(/;/g, '%3B');
    };

    NotificationIssue.prototype.getRepoUrl = function() {
      var packageName, packagePath, repo, repoUrl, _ref, _ref1, _ref2, _ref3, _ref4;
      packageName = this.getPackageName();
      if (packageName == null) {
        return;
      }
      repo = (_ref = atom.packages.getLoadedPackage(packageName)) != null ? (_ref1 = _ref.metadata) != null ? _ref1.repository : void 0 : void 0;
      repoUrl = (_ref2 = repo != null ? repo.url : void 0) != null ? _ref2 : repo;
      if (!repoUrl) {
        if (packagePath = atom.packages.resolvePackagePath(packageName)) {
          try {
            repo = (_ref3 = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json')))) != null ? _ref3.repository : void 0;
            repoUrl = (_ref4 = repo != null ? repo.url : void 0) != null ? _ref4 : repo;
          } catch (_error) {}
        }
      }
      repoUrl = repoUrl != null ? repoUrl.replace(/\.git$/, '') : void 0;
      return repoUrl;
    };

    NotificationIssue.prototype.getPackageNameFromFilePath = function(filePath) {
      var packageName, _ref, _ref1, _ref2, _ref3;
      if (!filePath) {
        return;
      }
      packageName = (_ref = /\/\.atom\/dev\/packages\/([^\/]+)\//.exec(filePath)) != null ? _ref[1] : void 0;
      if (packageName) {
        return packageName;
      }
      packageName = (_ref1 = /\\\.atom\\dev\\packages\\([^\\]+)\\/.exec(filePath)) != null ? _ref1[1] : void 0;
      if (packageName) {
        return packageName;
      }
      packageName = (_ref2 = /\/\.atom\/packages\/([^\/]+)\//.exec(filePath)) != null ? _ref2[1] : void 0;
      if (packageName) {
        return packageName;
      }
      packageName = (_ref3 = /\\\.atom\\packages\\([^\\]+)\\/.exec(filePath)) != null ? _ref3[1] : void 0;
      if (packageName) {
        return packageName;
      }
    };

    NotificationIssue.prototype.getPackageName = function() {
      var file, getPackageName, i, options, packageName, packagePath, packagePaths, stack, _i, _ref;
      options = this.notification.getOptions();
      if (!((options.stack != null) || (options.detail != null))) {
        return;
      }
      packagePaths = this.getPackagePathsByPackageName();
      for (packageName in packagePaths) {
        packagePath = packagePaths[packageName];
        if (packagePath.indexOf('.atom/dev/packages') > -1 || packagePath.indexOf('.atom/packages') > -1) {
          packagePaths[packageName] = fs.realpathSync(packagePath);
        }
      }
      getPackageName = (function(_this) {
        return function(filePath) {
          var packName, relativePath;
          if (path.isAbsolute(filePath)) {
            for (packName in packagePaths) {
              packagePath = packagePaths[packName];
              if (filePath === 'node.js') {
                continue;
              }
              relativePath = path.relative(packagePath, filePath);
              if (!/^\.\./.test(relativePath)) {
                return packName;
              }
            }
          }
          return _this.getPackageNameFromFilePath(filePath);
        };
      })(this);
      if ((options.detail != null) && (packageName = getPackageName(options.detail))) {
        return packageName;
      }
      if (options.stack != null) {
        stack = StackTraceParser.parse(options.stack);
        for (i = _i = 0, _ref = stack.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
          file = stack[i].file;
          if (!file) {
            return;
          }
          packageName = getPackageName(file);
          if (packageName != null) {
            return packageName;
          }
        }
      }
    };

    NotificationIssue.prototype.getPackagePathsByPackageName = function() {
      var pack, packagePathsByPackageName, _i, _len, _ref;
      packagePathsByPackageName = {};
      _ref = atom.packages.getLoadedPackages();
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        pack = _ref[_i];
        packagePathsByPackageName[pack.name] = pack.path;
      }
      return packagePathsByPackageName;
    };

    return NotificationIssue;

  })();

}).call(this);
