<commit_before>import Immutable from 'immutable'
import yaml from 'js-yaml'
import tv4 from 'tv4'
import swaggerSchema from 'swagger-schema-official/schema.json'

import Constraint from '../../models/Constraint'

import Context, {
    Parameter,
    ParameterContainer,
    Body,
    Response
} from '../../models/Core'

import {
    Info, Contact, License
} from '../../models/Utils'

import Group from '../../models/Group'
import Request from '../../models/Request'
import Auth from '../../models/Auth'
import URL from '../../models/URL'
import Item from '../../models/Item'

import ReferenceContainer from '../../models/references/Container'
import JSONSchemaReference from '../../models/references/JSONSchema'

export default class SwaggerParser {
    constructor() {
        this.context = new Context()
        this.item = new Item()
    }

    // @NotTested -> assumed valid
    parse(item) {
        this.item = new Item(item)
        const string = item.content
        const swaggerCollection = this._loadSwaggerCollection(string)
        const valid = this._validateSwaggerCollection(swaggerCollection)

        if (!valid) {
            const m = 'Invalid Swagger File (invalid schema / version < 2.0):\n'
            throw new Error(m + tv4.error)
        }

        if (swaggerCollection) {
            let refs = new ReferenceContainer()
            refs = refs.create(
                this._extractReferences(this.item, swaggerCollection)
            )

            let rootGroup = new Group()
            rootGroup = rootGroup.set('name', swaggerCollection.info.title)
            let pathLinkedRequests = this._applyFuncOverPathArchitecture(
                swaggerCollection,
                ::this._createRequest
            )

            rootGroup = this._createGroupTree(rootGroup, pathLinkedRequests)

            let info = this._extractContextInfo(swaggerCollection.info)

            let reqContext = new Context()
            reqContext = reqContext
                .set('group', rootGroup)
                .setIn([ 'references', 'schemas' ], refs)
                .set('info', info)

            this.context = reqContext

            return reqContext
        }
    }

    _extractContextInfo(_info) {
        if (!_info) {
            return new Info()
        }

        let contact = null
        if (_info.contact) {
            contact = new Contact({
                name: _info.contact.name || null,
                url: _info.contact.url || null,
                email: _info.contact.email || null
            })
        }

        let license = null
        if (_info.license) {
            license = new License({
                name: _info.license.name || null,
                url: _info.license.url || null
            })
        }

        let info = new Info({
            title: _info.title || null,
            description: _info.description || null,
            tos: _info.termsOfService || null,
            contact: contact,
            license: license,
            version: _info.version || null
        })

        return info
    }

    // @NotTested -> assumed valid
    _createRequest(swaggerCollection, path, method, content, description) {
        const url = this._extractUrlInfo(
            swaggerCollection,
            path,
            content
        )

        const container = this._extractParams(
            swaggerCollection,
            content
        )

        const responses = this._extractResponses(
            swaggerCollection, content
        )

        const bodies = this._extractBodies(swaggerCollection, content)

        let request = new Request()
        request = this._setTagsAndId(request, content)
        request = this._setSummary(request, path, content)
        request = this._setDescription(request, content, description)
        request = this._setBasicInfo(
            request,
            url,
            method,
            container,
            bodies,
            responses
        )
        request = this._setAuth(request, swaggerCollection, content)

        return request
    }

    _setTagsAndId(_request, content) {
        let request = _request
        if (content.tags) {
            let tags = new Immutable.List(content.tags)
            request = request.set('tags', tags)
        }

        if (content.operationId) {
            request = request.set('id', content.operationId)
        }

        return request
    }

    // @tested
    _setSummary(request, path, content) {
        if (content.summary) {
            return request.set('name', content.summary)
        }
        return request.set('name', path)
    }

    // @tested
    _setDescription(request, content, description) {
        let _description = []
        if (content.description) {
            _description.push(content.description)
        }

        if (description) {
            _description.push(description)
        }

        return request.set('description', _description.join('\n\n') || null)
    }

    // @tested
    _setBasicInfo(request, url, method, container, bodies, responses) {
        let _container = container || new ParameterContainer()
        let _bodies = bodies || new Immutable.List()
        let _responses = responses || new Immutable.List()

        return request.withMutations(req => {
            req
                .set('url', url)
                .set('method', method.toUpperCase())<commit_msg>improve swagger request naming strategy<commit_after>import Immutable from 'immutable'
import yaml from 'js-yaml'
import tv4 from 'tv4'
import swaggerSchema from 'swagger-schema-official/schema.json'

import Constraint from '../../models/Constraint'

import Context, {
    Parameter,
    ParameterContainer,
    Body,
    Response
} from '../../models/Core'

import {
    Info, Contact, License
} from '../../models/Utils'

import Group from '../../models/Group'
import Request from '../../models/Request'
import Auth from '../../models/Auth'
import URL from '../../models/URL'
import Item from '../../models/Item'

import ReferenceContainer from '../../models/references/Container'
import JSONSchemaReference from '../../models/references/JSONSchema'

export default class SwaggerParser {
    constructor() {
        this.context = new Context()
        this.item = new Item()
    }

    // @NotTested -> assumed valid
    parse(item) {
        this.item = new Item(item)
        const string = item.content
        const swaggerCollection = this._loadSwaggerCollection(string)
        const valid = this._validateSwaggerCollection(swaggerCollection)

        if (!valid) {
            const m = 'Invalid Swagger File (invalid schema / version < 2.0):\n'
            throw new Error(m + tv4.error)
        }

        if (swaggerCollection) {
            let refs = new ReferenceContainer()
            refs = refs.create(
                this._extractReferences(this.item, swaggerCollection)
            )

            let rootGroup = new Group()
            rootGroup = rootGroup.set('name', swaggerCollection.info.title)
            let pathLinkedRequests = this._applyFuncOverPathArchitecture(
                swaggerCollection,
                ::this._createRequest
            )

            rootGroup = this._createGroupTree(rootGroup, pathLinkedRequests)

            let info = this._extractContextInfo(swaggerCollection.info)

            let reqContext = new Context()
            reqContext = reqContext
                .set('group', rootGroup)
                .setIn([ 'references', 'schemas' ], refs)
                .set('info', info)

            this.context = reqContext

            return reqContext
        }
    }

    _extractContextInfo(_info) {
        if (!_info) {
            return new Info()
        }

        let contact = null
        if (_info.contact) {
            contact = new Contact({
                name: _info.contact.name || null,
                url: _info.contact.url || null,
                email: _info.contact.email || null
            })
        }

        let license = null
        if (_info.license) {
            license = new License({
                name: _info.license.name || null,
                url: _info.license.url || null
            })
        }

        let info = new Info({
            title: _info.title || null,
            description: _info.description || null,
            tos: _info.termsOfService || null,
            contact: contact,
            license: license,
            version: _info.version || null
        })

        return info
    }

    // @NotTested -> assumed valid
    _createRequest(swaggerCollection, path, method, content, description) {
        const url = this._extractUrlInfo(
            swaggerCollection,
            path,
            content
        )

        const container = this._extractParams(
            swaggerCollection,
            content
        )

        const responses = this._extractResponses(
            swaggerCollection, content
        )

        const bodies = this._extractBodies(swaggerCollection, content)

        let request = new Request()
        request = this._setTagsAndId(request, content)
        request = this._setSummary(request, path, content)
        request = this._setDescription(request, content, description)
        request = this._setBasicInfo(
            request,
            url,
            method,
            container,
            bodies,
            responses
        )
        request = this._setAuth(request, swaggerCollection, content)

        return request
    }

    _setTagsAndId(_request, content) {
        let request = _request
        if (content.tags) {
            let tags = new Immutable.List(content.tags)
            request = request.set('tags', tags)
        }

        if (content.operationId) {
            request = request.set('id', content.operationId)
        }

        return request
    }

    // @tested
    _setSummary(request, path, content) {
        if (content.summary) {
            return request.set('name', content.summary)
        }
        else if (content.operationId) {
            return request.set('name', content.operationId)
        }
        return request.set('name', path)
    }

    // @tested
    _setDescription(request, content, description) {
        let _description = []
        if (content.description) {
            _description.push(content.description)
        }

        if (description) {
            _description.push(description)
        }

        return request.set('description', _description.join('\n\n') || null)
    }

    // @tested
    _setBasicInfo(request, url, method, container, bodies, responses) {
        let _container = container || new ParameterContainer()
        let _bodies = bodies || new Immutable.List()
        let _responses = responses || new Immutable.List()

        return request.withMutations(req => {
            req
                .set('url', url)
                .set('method', method.toUpperCase())
{'fraction_non_alphanumeric': 0.1030027297543221, 'fraction_numerical': 0.0009099181073703367, 'mean_word_length': 1.792428861788618, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '494489', 'n_tokens_mistral': 2841, 'n_tokens_neox': 2759, 'n_words': 697}