import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

import prerelease from 'semver/functions/prerelease';

function isUnstableVersion(version) {
  return !!prerelease(version);
}

export default Route.extend({
  flashMessages: service(),

  async model(params) {
    const requestedVersion = params.version_num;
    const crate = this.modelFor('crate');
    const maxVersion = crate.max_version;

    let versions = await crate.get('versions');

    // Fallback to the crate's last stable version
    // If `max_version` is `0.0.0` then all versions have been yanked
    if (!params.version_num && maxVersion !== '0.0.0') {
      if (isUnstableVersion(maxVersion)) {
        const latestStableVersion = versions.find(version => {
          // Find the latest version that is stable AND not-yanked.
          if (!isUnstableVersion(version.num) && !version.yanked) {
            return version;
          }
        });

        if (latestStableVersion == null) {
          // Cannot find any version that is stable AND not-yanked.
          // The fact that "maxVersion" itself cannot be found means that
          // we have to fall back to the latest one that is unstable....
          const latestUnyankedVersion = versions.find(version => {
            // Find the latest version that is stable AND not-yanked.
            if (!version.yanked) {
              return version;
            }
          });

          if (latestStableVersion == null) {
            // There's not even any unyanked version...
            params.version_num = maxVersion;
          } else {
            params.version_num = latestUnyankedVersion;
          }
        } else {
          params.version_num = latestStableVersion.num;
        }
      } else {
        params.version_num = maxVersion;
      }
    }

    const version = versions.find(version => version.num === params.version_num);
    if (params.version_num && !version) {
      this.flashMessages.queue(`Version '${params.version_num}' of crate '${crate.name}' does not exist`);
    }

    return {
      crate,
      requestedVersion,
      version: version || versions.find(version => version.num === maxVersion) || versions.objectAt(0),
    };
  },

  setupController(controller, model) {
    this._super(...arguments);
    controller.loadReadmeTask.perform();

    let { crate } = model;
    if (!crate.documentation || crate.documentation.startsWith('https://docs.rs/')) {
      controller.loadDocsBuilds.perform();
    }
  },

  serialize(model) {
    let version_num = model.num;
    return { version_num };
  },
});

@@ -707,73 +707,8 @@
 ) %7B%0A
-        const latestStableVersion = versions.find(version =%3E %7B%0A  
     
@@ -781,117 +781,111 @@
     
-  if (!isUnstableVersion(version.num) && !version.yanked) %7B%0A            return version;%0A          %7D%0A        %7D
+const latestStableVersion = versions.find(version =%3E !isUnstableVersion(version.num) && !version.yanked
 );%0A%0A
@@ -1146,77 +1146,9 @@
 ...%0A
-          const latestUnyankedVersion = versions.find(version =%3E %7B%0A  
+%0A
     
@@ -1185,34 +1185,20 @@
 on that 
-is stable AND 
 not
--
+ 
 yanked.%0A
@@ -1211,88 +1211,78 @@
     
-  if (!version.yanked) %7B%0A              return version;%0A            %7D%0A          %7D
+const latestUnyankedVersion = versions.find(version =%3E !version.yanked
 );%0A%0A

Simplify `version.find()` calls