var entry = require('../../lib/util/entry');

var should = require('chai').should();

describe('util.entry', function () {
    describe('effectiveDate', function () {
        it('should return dateWritten for a MedicationPrescription', function () {
            var input = {
                content: {
                    resourceType: 'MedicationPrescription',
                    dateWritten: '2012-03-08T09:00:00.000Z'
                }
            };

            var result = entry.effectiveDate(input);

            should.exist(result);
            result.should.be.a('Date');
            result.toISOString().should.equal('2012-03-08T09:00:00.000Z');
        });

        it('should return dateAsserted for a Condition', function () {
            var input = {
                content: {
                    resourceType: 'Condition',
                    dateAsserted: '2012-03-08T09:00:00.000Z'
                }
            };

            var result = entry.effectiveDate(input);

            should.exist(result);
            result.should.be.a('Date');
            result.toISOString().should.equal('2012-03-08T09:00:00.000Z');
        });

        it('should return recordedDate for an AllergyIntolerance', function () {
            var input = {
                content: {
                    resourceType: 'AllergyIntolerance',
                    recordedDate: '2012-03-08T09:00:00.000Z'
                }
            };

            var result = entry.effectiveDate(input);

            should.exist(result);
            result.should.be.a('Date');
            result.toISOString().should.equal('2012-03-08T09:00:00.000Z');
        });

        it('should return issued for an Observation', function () {
            var input = {
                content: {
                    resourceType: 'Observation',
                    issued: '2012-03-08T09:00:00.000Z'
                }
            };

            var result = entry.effectiveDate(input);

            should.exist(result);
            result.should.be.a('Date');
            result.toISOString().should.equal('2012-03-08T09:00:00.000Z');
        });

        it('should return undefined when no date value found', function () {
            var input = {
                content: {
                    resourceType: 'Observation'
                }
            };

            var result = entry.effectiveDate(input);

            should.not.exist(result);
        });
    });

    describe('effectiveCode', function () {
        it('should return code.coding[0].code for a Condition', function () {
            var input = {
                content: {
                    resourceType: 'Condition',
                    code: {
                        coding: [
                            {
                                code: 'fubar'
                            }
                        ]
                    }
                }
            };

            var result = entry.effectiveCode(input);

            should.exist(result);
            result.should.be.a('string');
            result.should.equal('fubar');
        });

        it('should return name.coding[0] for an Observation', function () {
            var input = {
                content: {
                    resourceType: 'Observation',
                    name: {
                        coding: [
                            {
                                code: 'fubar'
                            }
                        ]
                    }
                }
            };

            var result = entry.effectiveCode(input);

            should.exist(result);
            result.should.be.a('string');
            result.should.equal('fubar');
        });

        it('should return undefined when no code found', function () {
            var input = {
                content: {
                    resourceType: 'Foo'
                }
            };

            var result = entry.effectiveCode(input);

            should.not.exist(result);
        });

        it('should return undefined when no coding found', function () {
            var input = {
                content: {
                    resourceType: 'Condition',
                    code: {
                        text: 'Uncoded condition'
                    }
                }
            };

            var result = entry.effectiveCode(input);

            should.not.exist(result);
        });

        it('should return undefined when coding has no entries', function () {
            var input = {
                content: {
                    resourceType: 'Condition',
                    code: {
                        coding: []
                    }
                }
            };

            var result = entry.effectiveCode(input);

            should.not.exist(result);
        });

        it('should return undefined when first code in coding has no value', function () {
            var input = {
                content: {
                    resourceType: 'Condition',
                    code: {
                        coding: [
                            {
                                display: 'No code value supplied'
                            }
                        ]
                    }
                }
            };

            var result = entry.effectiveCode(input);

            should.not.exist(result);
        });
    });

    describe('isCodeable', function () {
        var fn = entry.isCodeable;

        it('should return true when resource could be coded', function () {
            var candidate = {
                content: {
                    resourceType: 'AllergyIntolerance'
                }
            };

            var result = fn(candidate);

            should.exist(result);
            result.should.equal(true);
        });

        it('should return false when resource cannot be coded', function () {
            var candidate = {
                content: {
                    resourceType: 'Location'
                }
            };

            var result = fn(candidate);

            should.exist(result);
            result.should.equal(false);
        });
    });

    describe('coding', function(){
        it('should return content.substance.coding for AllergyIntolerance', function(){
            var input = {
                content: {
                    resourceType: 'AllergyIntolerance',
                    substance: {
                        coding: [
                            {
                                system: 'READ2',
                                code: 'XYZ..',
                                display: 'Matched concept from target system'
                            },
                            {
                                system: 'SNOMED',
                                code: '169461009',
                                display: 'Concept from alternative system'
                            }
                        ]
                    }
                }
            };

            var result = entry.coding(input);

            should.exist(result);
            result.should.deep.equal(input.content.substance.coding);
        });

        it('should return content.code.coding for Condition', function(){
            var input = {
                content: {
                    resourceType: 'Condition',
                    code: {
                        coding: [
                            {
                                system: 'READ2',
                                code: 'XYZ..',
                                display: 'Matched concept from target system'
                            },
                            {
                                system: 'SNOMED',
                                code: '169461009',
                                display: 'Concept from alternative system'
                            }
                        ]
                    }
                }
            };

            var result = entry.coding(input);

            should.exist(result);
            result.should.deep.equal(input.content.code.coding);
        });

        it('should return content.reason.coding for Encounter', function(){
            var input = {
                content: {
                    resourceType: 'Encounter',
                    reason: {
                        coding: [
                            {
                                system: 'READ2',
                                code: 'XYZ..',
                                display: 'Matched concept from target system'
                            },
                            {
                                system: 'SNOMED',
                                code: '169461009',
                                display: 'Concept from alternative system'
                            }
                        ]
                    }
                }
            };

            var result = entry.coding(input);

            should.exist(result);
            result.should.deep.equal(input.content.reason.coding);
        });

        it('should return content.vaccineType.coding for Immunization', function(){
            var input = {
                content: {
                    resourceType: 'Immunization',
                    vaccineType: {
                        coding: [
                            {
                                system: 'READ2',
                                code: 'XYZ..',
                                display: 'Matched concept from target system'
                            },
                            {
                                system: 'SNOMED',
                                code: '169461009',
                                display: 'Concept from alternative system'
                            }
                        ]
                    }
                }
            };

            var result = entry.coding(input);

            should.exist(result);
            result.should.deep.equal(input.content.vaccineType.coding);
        });

        it('should return content.code.coding for Medication', function(){
            var input = {
                content: {
                    resourceType: 'Medication',
                    code: {
                        coding: [
                            {
                                system: 'READ2',
                                code: 'XYZ..',
                                display: 'Matched concept from target system'
                            },
                            {
                                system: 'SNOMED',
                                code: '169461009',
                                display: 'Concept from alternative system'
                            }
                        ]
                    }
                }
            };

            var result = entry.coding(input);

            should.exist(result);
            result.should.deep.equal(input.content.code.coding);
        });

        it('should return content.name.coding for Observation', function(){
            var input = {
                content: {
                    resourceType: 'Observation',
                    name: {
                        coding: [
                            {
                                system: 'READ2',
                                code: 'XYZ..',
                                display: 'Matched concept from target system'
                            },
                            {
                                system: 'SNOMED',
                                code: '169461009',
                                display: 'Concept from alternative system'
                            }
                        ]
                    }
                }
            };

            var result = entry.coding(input);

            should.exist(result);
            result.should.deep.equal(input.content.name.coding);
        });

        it('should be undefined when no coding', function(){
            var input = {
                content: {
                    resourceType: 'Observation',
                    name: {
                    }
                }
            };

            var result = entry.coding(input);

            should.not.exist(result);
        });

        it('should be undefined when no codeable concept', function(){
            var input = {
                content: {
                    resourceType: 'Observation'
                }
            };

            var result = entry.coding(input);

            should.not.exist(result);
        });
    });
});