// @include org.kohsuke.stapler.codemirror.lib.codemirror
// Initiate ModeTest and set defaults
var MT = ModeTest;
MT.modeName = 'css';
MT.modeOptions = {};

// Requires at least one media query
MT.testMode(
  'atMediaEmpty',
  '@media { }',
  [
    'def', '@media',
    null, ' ',
    'error', '{',
    null, ' }'
  ]
);

MT.testMode(
  'atMediaMultiple',
  '@media not screen and (color), not print and (color) { }',
  [
    'def', '@media',
    null, ' ',
    'keyword', 'not',
    null, ' ',
    'attribute', 'screen',
    null, ' ',
    'operator', 'and',
    null, ' (',
    'property', 'color',
    null, '), ',
    'keyword', 'not',
    null, ' ',
    'attribute', 'print',
    null, ' ',
    'operator', 'and',
    null, ' (',
    'property', 'color',
    null, ') { }'
  ]
);

MT.testMode(
  'atMediaCheckStack',
  '@media screen { } foo { }',
  [
    'def', '@media',
    null, ' ',
    'attribute', 'screen',
    null, ' { } ',
    'tag', 'foo',
    null, ' { }'
  ]
);

MT.testMode(
  'atMediaCheckStack',
  '@media screen (color) { } foo { }',
  [
    'def', '@media',
    null, ' ',
    'attribute', 'screen',
    null, ' (',
    'property', 'color',
    null, ') { } ',
    'tag', 'foo',
    null, ' { }'
  ]
);

MT.testMode(
  'atMediaCheckStackInvalidAttribute',
  '@media foobarhello { } foo { }',
  [
    'def', '@media',
    null, ' ',
    'attribute error', 'foobarhello',
    null, ' { } ',
    'tag', 'foo',
    null, ' { }'
  ]
);

// Error, because "and" is only allowed immediately preceding a media expression
MT.testMode(
  'atMediaInvalidAttribute',
  '@media foobarhello { }',
  [
    'def', '@media',
    null, ' ',
    'attribute error', 'foobarhello',
    null, ' { }'
  ]
);

// Error, because "and" is only allowed immediately preceding a media expression
MT.testMode(
  'atMediaInvalidAnd',
  '@media and screen { }',
  [
    'def', '@media',
    null, ' ',
    'error', 'and',
    null, ' ',
    'attribute', 'screen',
    null, ' { }'
  ]
);

// Error, because "not" is only allowed as the first item in each media query
MT.testMode(
  'atMediaInvalidNot',
  '@media screen not (not) { }',
  [
    'def', '@media',
    null, ' ',
    'attribute', 'screen',
    null, ' ',
    'error', 'not',
    null, ' (',
    'error', 'not',
    null, ') { }'
  ]
);

// Error, because "only" is only allowed as the first item in each media query
MT.testMode(
  'atMediaInvalidOnly',
  '@media screen only (only) { }',
  [
    'def', '@media',
    null, ' ',
    'attribute', 'screen',
    null, ' ',
    'error', 'only',
    null, ' (',
    'error', 'only',
    null, ') { }'
  ]
);

// Error, because "foobarhello" is neither a known type or property, but
// property was expected (after "and"), and it should be in parenthese.
MT.testMode(
  'atMediaUnknownType',
  '@media screen and foobarhello { }',
  [
    'def', '@media',
    null, ' ',
    'attribute', 'screen',
    null, ' ',
    'operator', 'and',
    null, ' ',
    'error', 'foobarhello',
    null, ' { }'
  ]
);

// Error, because "color" is not a known type, but is a known property, and
// should be in parentheses.
MT.testMode(
  'atMediaInvalidType',
  '@media screen and color { }',
  [
    'def', '@media',
    null, ' ',
    'attribute', 'screen',
    null, ' ',
    'operator', 'and',
    null, ' ',
    'error', 'color',
    null, ' { }'
  ]
);

// Error, because "print" is not a known property, but is a known type,
// and should not be in parenthese.
MT.testMode(
  'atMediaInvalidProperty',
  '@media screen and (print) { }',
  [
    'def', '@media',
    null, ' ',
    'attribute', 'screen',
    null, ' ',
    'operator', 'and',
    null, ' (',
    'error', 'print',
    null, ') { }'
  ]
);

// Soft error, because "foobarhello" is not a known property or type.
MT.testMode(
  'atMediaUnknownProperty',
  '@media screen and (foobarhello) { }',
  [
    'def', '@media',
    null, ' ',
    'attribute', 'screen',
    null, ' ',
    'operator', 'and',
    null, ' (',
    'property error', 'foobarhello',
    null, ') { }'
  ]
);

MT.testMode(
  'tagSelector',
  'foo { }',
  [
    'tag', 'foo',
    null, ' { }'
  ]
);

MT.testMode(
  'classSelector',
  '.foo-bar_hello { }',
  [
    'qualifier', '.foo-bar_hello',
    null, ' { }'
  ]
);

MT.testMode(
  'idSelector',
  '#foo { #foo }',
  [
    'builtin', '#foo',
    null, ' { ',
    'error', '#foo',
    null, ' }'
  ]
);

MT.testMode(
  'tagSelectorUnclosed',
  'foo { margin: 0 } bar { }',
  [
    'tag', 'foo',
    null, ' { ',
    'property', 'margin',
    'operator', ':',
    null, ' ',
    'number', '0',
    null, ' } ',
    'tag', 'bar',
    null, ' { }'
  ]
);

MT.testMode(
  'tagStringNoQuotes',
  'foo { font-family: hello world; }',
  [
    'tag', 'foo',
    null, ' { ',
    'property', 'font-family',
    'operator', ':',
    null, ' ',
    'variable-2', 'hello',
    null, ' ',
    'variable-2', 'world',
    null, '; }'
  ]
);

MT.testMode(
  'tagStringDouble',
  'foo { font-family: "hello world"; }',
  [
    'tag', 'foo',
    null, ' { ',
    'property', 'font-family',
    'operator', ':',
    null, ' ',
    'string', '"hello world"',
    null, '; }'
  ]
);

MT.testMode(
  'tagStringSingle',
  'foo { font-family: \'hello world\'; }',
  [
    'tag', 'foo',
    null, ' { ',
    'property', 'font-family',
    'operator', ':',
    null, ' ',
    'string', '\'hello world\'',
    null, '; }'
  ]
);

MT.testMode(
  'tagColorKeyword',
  'foo { color: black; }',
  [
    'tag', 'foo',
    null, ' { ',
    'property', 'color',
    'operator', ':',
    null, ' ',
    'keyword', 'black',
    null, '; }'
  ]
);

MT.testMode(
  'tagColorHex3',
  'foo { background: #fff; }',
  [
    'tag', 'foo',
    null, ' { ',
    'property', 'background',
    'operator', ':',
    null, ' ',
    'atom', '#fff',
    null, '; }'
  ]
);

MT.testMode(
  'tagColorHex6',
  'foo { background: #ffffff; }',
  [
    'tag', 'foo',
    null, ' { ',
    'property', 'background',
    'operator', ':',
    null, ' ',
    'atom', '#ffffff',
    null, '; }'
  ]
);

MT.testMode(
  'tagColorHex4',
  'foo { background: #ffff; }',
  [
    'tag', 'foo',
    null, ' { ',
    'property', 'background',
    'operator', ':',
    null, ' ',
    'atom error', '#ffff',
    null, '; }'
  ]
);

MT.testMode(
  'tagColorHexInvalid',
  'foo { background: #ffg; }',
  [
    'tag', 'foo',
    null, ' { ',
    'property', 'background',
    'operator', ':',
    null, ' ',
    'atom error', '#ffg',
    null, '; }'
  ]
);

MT.testMode(
  'tagNegativeNumber',
  'foo { margin: -5px; }',
  [
    'tag', 'foo',
    null, ' { ',
    'property', 'margin',
    'operator', ':',
    null, ' ',
    'number', '-5px',
    null, '; }'
  ]
);

MT.testMode(
  'tagPositiveNumber',
  'foo { padding: 5px; }',
  [
    'tag', 'foo',
    null, ' { ',
    'property', 'padding',
    'operator', ':',
    null, ' ',
    'number', '5px',
    null, '; }'
  ]
);

MT.testMode(
  'tagVendor',
  'foo { -foo-box-sizing: -foo-border-box; }',
  [
    'tag', 'foo',
    null, ' { ',
    'meta', '-foo-',
    'property', 'box-sizing',
    'operator', ':',
    null, ' ',
    'meta', '-foo-',
    'string-2', 'border-box',
    null, '; }'
  ]
);

MT.testMode(
  'tagBogusProperty',
  'foo { barhelloworld: 0; }',
  [
    'tag', 'foo',
    null, ' { ',
    'property error', 'barhelloworld',
    'operator', ':',
    null, ' ',
    'number', '0',
    null, '; }'
  ]
);

MT.testMode(
  'tagTwoProperties',
  'foo { margin: 0; padding: 0; }',
  [
    'tag', 'foo',
    null, ' { ',
    'property', 'margin',
    'operator', ':',
    null, ' ',
    'number', '0',
    null, '; ',
    'property', 'padding',
    'operator', ':',
    null, ' ',
    'number', '0',
    null, '; }'
  ]
);
//
//MT.testMode(
//  'tagClass',
//  '@media only screen and (min-width: 500px), print {foo.bar#hello { color: black !important; background: #f00; margin: -5px; padding: 5px; -foo-box-sizing: border-box; } /* world */}',
//  [
//    'def', '@media',
//    null, ' ',
//    'keyword', 'only',
//    null, ' ',
//    'attribute', 'screen',
//    null, ' ',
//    'operator', 'and',
//    null, ' ',
//    'bracket', '(',
//    'property', 'min-width',
//    'operator', ':',
//    null, ' ',
//    'number', '500px',
//    'bracket', ')',
//    null, ', ',
//    'attribute', 'print',
//    null, ' {',
//    'tag', 'foo',
//    'qualifier', '.bar',
//    'header', '#hello',
//    null, ' { ',
//    'property', 'color',
//    'operator', ':',
//    null, ' ',
//    'keyword', 'black',
//    null, ' ',
//    'keyword', '!important',
//    null, '; ',
//    'property', 'background',
//    'operator', ':',
//    null, ' ',
//    'atom', '#f00',
//    null, '; ',
//    'property', 'padding',
//    'operator', ':',
//    null, ' ',
//    'number', '5px',
//    null, '; ',
//    'property', 'margin',
//    'operator', ':',
//    null, ' ',
//    'number', '-5px',
//    null, '; ',
//    'meta', '-foo-',
//    'property', 'box-sizing',
//    'operator', ':',
//    null, ' ',
//    'string-2', 'border-box',
//    null, '; } ',
//    'comment', '/* world */',
//    null, '}'
//  ]
//);