<commit_before>import { createSelector } from 'reselect';
import Immutable, { Record }from 'immutable';
import keymirror from 'keymirror';
import { api, logger } from './commons';
import fetch from 'isomorphic-fetch';

require('es6-promise').polyfill();

api.init({
  latency: 100
});

export const SearchOptions = Record({
  limit: 50,
  page: 1,
  pages: 0,
  total: 0
});

export const Stats = Record({
  installations: null,
  installationsPerVersion: null,
  installationsPercentage: null,
  installationsPercentagePerVersion: null,
  name: null,
});

export const Plugin = Record({
  id: null,
  name: null,
  title: null,
  buildDate: null,
  releaseTimestamp: null,
  version: null,
  previousVersion: null,
  previousTimestamp: null,
  compatibleSinceVersion: null,
  scm: null,
  url: null,
  sha1: null,
  wiki: null,
  excerpt: null,
  iconDom: null,
  download:null,
  trend:null,
  category: null,
  requiredCore: null,
  developers: [],
  labels: [],
  categories:[],
  dependencies: [],
  stats: Stats,
  detail:null,
});

export const State = Record({
  plugins: null,
  plugin: Plugin,
  isFetching: false,
  labels: null,
  categories:null,
  labelFilter: Record({//fixme: that should become label: search, sort: field
    field: 'title',
    searchField: null,
    asc: false,
    search: []
  }),
  searchOptions: SearchOptions,
});

// fetch helper
const fetchOptions = { credentials: 'same-origin' };
function checkStatus(response) {
  if (response.status >= 300 || response.status < 200) {
    const error = new Error(response.statusText);
    error.response = response;
    throw error;
  }
  return response;
}

function parseJSON(response) {
  return response.json();
}

export const ACTION_TYPES = keymirror({
  CLEAR_PLUGINS_DATA: null,
  FETCH_PLUGINS_DATA: null,
  SET_PLUGINS_DATA: null,
  SET_PLUGIN_DATA: null,
  CLEAR_PLUGIN_DATA: null,
  SET_LABEL_FILTER: null,
  SET_LABELS: null,
  SET_CATEGORIES: null,
  SET_QUERY_INFO: null
});

export const actionHandlers = {
  [ACTION_TYPES.CLEAR_PLUGIN_DATA](state) {
    return state.set('plugin', null);
  },
  [ACTION_TYPES.SET_PLUGIN_DATA](state, { payload: record }){
    return state.set('plugin', record);
  },
  [ACTION_TYPES.CLEAR_PLUGINS_DATA](state) {
    return state.set('plugins', Immutable.Map());
  },
  [ACTION_TYPES.FETCH_PLUGINS_DATA](state, {}){
    return state.set('isFetching', !state.isFetching);
  },
  [ACTION_TYPES.SET_PLUGINS_DATA](state, { payload }){
    return state.set('plugins', payload);
  },
  [ACTION_TYPES.SET_LABELS](state, { payload }){
    return state.set('labels', payload);
  },
  [ACTION_TYPES.SET_CATEGORIES](state, { payload }){
    return state.set('categories', payload);
  },
  [ACTION_TYPES.SET_QUERY_INFO](state, { payload }){
    return state.set('searchOptions', payload);
  }
};

export const actions = {

  clearPluginsData: () => ({ type: ACTION_TYPES.CLEAR_PLUGINS_DATA }),
  clearPluginData: () => ({ type: ACTION_TYPES.CLEAR_PLUGINS_DATA }),

  fetchPluginData: () => ({ type: ACTION_TYPES.FETCH_PLUGINS_DATA }),

  getPlugin(name) {
    return (dispatch, getState) => {
      dispatch({ type: ACTION_TYPES.CLEAR_PLUGIN_DATA });
      const plugins = getState().resources.plugins;
      let plugin;
      if (plugins) {
        plugin = plugins.filter((plugin) => plugin.name === name);
      }
      const urlDetail = `/detail/${name}`;
      if(!plugins || !plugin || plugin.size === 0) {
        const url = `/plugin/${name}`;
        return fetch(url, fetchOptions)
          .then(checkStatus)
          .then(parseJSON)
          .then(data => {
            return fetch(urlDetail, fetchOptions)
              .then(checkStatus)
              .then(parseJSON)
              .then(detailData => {
                const detail = detailData.details;
                const record = new Plugin(data);
                dispatch({
                  type: ACTION_TYPES.SET_PLUGIN_DATA,
                  payload: record.set('detail', detail),
                });
              });
          });
      } else {
        const record = plugin.toArray()[0];
        return fetch(urlDetail, fetchOptions)
          .then(checkStatus)
          .then(parseJSON)
          .then(detailData => {
            const detail = detailData.details;
            dispatch({
              type: ACTION_TYPES.SET_PLUGIN_DATA,
              payload: record.set('detail', detail),
            });
          });
      }
    };
  },

  generateCategoryData: () =>{
    return (dispatch) => {
      return api.getJSON('/categories', (error, data) => {
        if (data && data.categories){
          dispatch({
            type: ACTION_TYPES.SET_CATEGORIES,
            payload: Immutable.List(data.docs)
          });
        }
      })
    };
  },

  generateLabelData: () => {
    return (dispatch) => {
      return api.getJSON('/labels',(error, data) => {
        if (data && data.labels) {
          dispatch({
            type: ACTION_TYPES.SET_LABELS,
            payload: Immutable.List(data.docs)
          });
        }
      });
    };
  },

  generatePluginData(query={}) {
    return (dispatch) => {
      logger.log(query);<commit_msg>[CBN-279] matching category prop name<commit_after>import { createSelector } from 'reselect';
import Immutable, { Record }from 'immutable';
import keymirror from 'keymirror';
import { api, logger } from './commons';
import fetch from 'isomorphic-fetch';

require('es6-promise').polyfill();

api.init({
  latency: 100
});

export const SearchOptions = Record({
  limit: 50,
  page: 1,
  pages: 0,
  total: 0
});

export const Stats = Record({
  installations: null,
  installationsPerVersion: null,
  installationsPercentage: null,
  installationsPercentagePerVersion: null,
  name: null,
});

export const Plugin = Record({
  id: null,
  name: null,
  title: null,
  buildDate: null,
  releaseTimestamp: null,
  version: null,
  previousVersion: null,
  previousTimestamp: null,
  compatibleSinceVersion: null,
  scm: null,
  url: null,
  sha1: null,
  wiki: null,
  excerpt: null,
  iconDom: null,
  download:null,
  trend:null,
  category: null,
  requiredCore: null,
  developers: [],
  labels: [],
  categories:[],
  dependencies: [],
  stats: Stats,
  detail:null,
});

export const State = Record({
  plugins: null,
  plugin: Plugin,
  isFetching: false,
  labels: null,
  categories:null,
  labelFilter: Record({//fixme: that should become label: search, sort: field
    field: 'title',
    searchField: null,
    asc: false,
    search: []
  }),
  searchOptions: SearchOptions,
});

// fetch helper
const fetchOptions = { credentials: 'same-origin' };
function checkStatus(response) {
  if (response.status >= 300 || response.status < 200) {
    const error = new Error(response.statusText);
    error.response = response;
    throw error;
  }
  return response;
}

function parseJSON(response) {
  return response.json();
}

export const ACTION_TYPES = keymirror({
  CLEAR_PLUGINS_DATA: null,
  FETCH_PLUGINS_DATA: null,
  SET_PLUGINS_DATA: null,
  SET_PLUGIN_DATA: null,
  CLEAR_PLUGIN_DATA: null,
  SET_LABEL_FILTER: null,
  SET_LABELS: null,
  SET_CATEGORIES: null,
  SET_QUERY_INFO: null
});

export const actionHandlers = {
  [ACTION_TYPES.CLEAR_PLUGIN_DATA](state) {
    return state.set('plugin', null);
  },
  [ACTION_TYPES.SET_PLUGIN_DATA](state, { payload: record }){
    return state.set('plugin', record);
  },
  [ACTION_TYPES.CLEAR_PLUGINS_DATA](state) {
    return state.set('plugins', Immutable.Map());
  },
  [ACTION_TYPES.FETCH_PLUGINS_DATA](state, {}){
    return state.set('isFetching', !state.isFetching);
  },
  [ACTION_TYPES.SET_PLUGINS_DATA](state, { payload }){
    return state.set('plugins', payload);
  },
  [ACTION_TYPES.SET_LABELS](state, { payload }){
    return state.set('labels', payload);
  },
  [ACTION_TYPES.SET_CATEGORIES](state, { payload }){
    return state.set('categories', payload);
  },
  [ACTION_TYPES.SET_QUERY_INFO](state, { payload }){
    return state.set('searchOptions', payload);
  }
};

export const actions = {

  clearPluginsData: () => ({ type: ACTION_TYPES.CLEAR_PLUGINS_DATA }),
  clearPluginData: () => ({ type: ACTION_TYPES.CLEAR_PLUGINS_DATA }),

  fetchPluginData: () => ({ type: ACTION_TYPES.FETCH_PLUGINS_DATA }),

  getPlugin(name) {
    return (dispatch, getState) => {
      dispatch({ type: ACTION_TYPES.CLEAR_PLUGIN_DATA });
      const plugins = getState().resources.plugins;
      let plugin;
      if (plugins) {
        plugin = plugins.filter((plugin) => plugin.name === name);
      }
      const urlDetail = `/detail/${name}`;
      if(!plugins || !plugin || plugin.size === 0) {
        const url = `/plugin/${name}`;
        return fetch(url, fetchOptions)
          .then(checkStatus)
          .then(parseJSON)
          .then(data => {
            return fetch(urlDetail, fetchOptions)
              .then(checkStatus)
              .then(parseJSON)
              .then(detailData => {
                const detail = detailData.details;
                const record = new Plugin(data);
                dispatch({
                  type: ACTION_TYPES.SET_PLUGIN_DATA,
                  payload: record.set('detail', detail),
                });
              });
          });
      } else {
        const record = plugin.toArray()[0];
        return fetch(urlDetail, fetchOptions)
          .then(checkStatus)
          .then(parseJSON)
          .then(detailData => {
            const detail = detailData.details;
            dispatch({
              type: ACTION_TYPES.SET_PLUGIN_DATA,
              payload: record.set('detail', detail),
            });
          });
      }
    };
  },

  generateCategoryData: () =>{
    return (dispatch) => {
      return api.getJSON('/categories', (error, data) => {
        if (data && data.categories){
          dispatch({
            type: ACTION_TYPES.SET_CATEGORIES,
            payload: Immutable.List(data.categories)
          });
        }
      })
    };
  },

  generateLabelData: () => {
    return (dispatch) => {
      return api.getJSON('/labels',(error, data) => {
        if (data && data.labels) {
          dispatch({
            type: ACTION_TYPES.SET_LABELS,
            payload: Immutable.List(data.docs)
          });
        }
      });
    };
  },

  generatePluginData(query={}) {
    return (dispatch) => {
      logger.log(query);
{'fraction_non_alphanumeric': 0.13975275255939734, 'fraction_numerical': 0.0037666602279312345, 'mean_word_length': 2.754532269760696, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6490549', 'n_tokens_mistral': 3340, 'n_tokens_neox': 3326, 'n_words': 677}