/*
 * we should format labels in a readable form like
 *			 label="\
 *			 {cnt_deliver:|\
 *				 Filter obj.-\>resp.|\
 *				 {vcl_deliver\{\}|\
 *				 {req.*|resp.*}}|\
 *				 {restart|<deliver>deliver|<synth>synth}}"
 *
 * <rant>
 * ... but some servers in the v-c.o build farm use old graphviz 2.26.3
 * which cannot handle labels with additional whitespace properly, so
 * for the time being we need to fall back into dark middle ages and
 * use illegibly long lines
 * </rant>
 * -- slink 20141013
 */

digraph cache_req_fsm {
	margin="0.25"
	ranksep="0.5"
	center="1"

	//// XXX does this belong here? -- from cache_vcl.c
	/*
	vcl_load [label = "vcl.load",shape=plaintext]
	vcl_load -> init
	init [
	      shape=record
	      label="
	      {VCL_Load:|
		      {vcl_init}|
		      {<ok>ok|<fail>fail}}"
	]
	init:ok -> ok
	init:fail -> fail

	vcl_discard [label = "vcl.discard",shape=plaintext]
	vcl_discard -> fini
	fini [
	      shape=record
	      label="
	      {VCL_Nuke:|
		      {vcl_fini}|
		      {<ok>ok}}"
	]
	fini:ok -> ok
	*/

	acceptor [shape=hexagon label="Request received"]
	label_select [shape=hexagon label="LABEL"]
	ESI_REQ [shape=hexagon label="ESI request"]
	RESTART [shape=plaintext]

	ESI_REQ -> recv
	SYNTH [shape=plaintext]
	FAIL [shape=plaintext]
	acceptor -> recv [style=bold]
	label_select -> recv [style=bold]

	subgraph xcluster_deliver {
		/* cnt_deliver() */
		deliver [
			 shape=record
			 label="{cnt_deliver:|Filter obj.-\>resp.|{vcl_deliver\{\}|{req.*|resp.*}}|{fail|<restart>restart|<deliver>deliver|<synth>synth}}"
		]

		deliver:deliver:s -> V1D_Deliver [style=bold,color=green]
		deliver:deliver:s -> V1D_Deliver [style=bold,color=red]
		deliver:deliver:s -> V1D_Deliver [style=bold,color=blue]

		stream [label="stream?\nbody",style=filled,color=turquoise]
		stream -> V1D_Deliver [style=dotted]
	}

	V1D_Deliver -> DONE

	/* cnt_synth() */
	subgraph xcluster_synth {
		synth [
		       shape=record
		       label="{cnt_synth:|{vcl_synth\{\}|{req.*|resp.*}}|{fail|<del>deliver|<restart>restart}}"
		]

		FAIL -> synth [color=purple]
		SYNTH -> synth [color=purple]
		synth:del:s -> V1D_Deliver [color=purple]
	}

	subgraph cluster_backend {
		style=filled
		color=aliceblue

		"see backend graph" [shape=plaintext]

		node [shape=box,
		      style=filled,
		      color=turquoise]

		BGFETCH
		FETCH
		FETCH_DONE
		FETCH_FAIL
	}

	lookup2:deliver:s -> BGFETCH [label="parallel\nif obj expired",
				      color=green]
	FETCH_FAIL -> synth [color=purple]

	FETCH_DONE -> deliver [style=bold,color=red]
	FETCH_DONE -> deliver [style=bold,color=blue]
	FETCH -> FETCH_DONE [style=dotted]
	FETCH -> FETCH_FAIL [style=dotted]
	/* cnt_lookup() */
	subgraph xcluster_lookup {
		lookup [
			shape=record
			color=grey
			fontcolor=grey
			label="{<top>cnt_lookup:|hash lookup|{<h>hit?|<miss>miss?|<hfm>hit-for-miss?|<hfp>hit-for-pass?|<busy>busy?}}"
		]
		lookup2 [
			 shape=record
			 label="{<top>cnt_lookup:|{vcl_hit\{\}|{req.*|obj.*}}|{fail|<deliver>deliver|<pass>pass|restart|synth}}"
		]
	}
	lookup:busy:s -> lookup:top:ne [label=" waitinglist",
				       color=grey,
				       fontcolor=grey]
	lookup:miss:s -> miss [style=bold,color=blue]
	lookup:hfm:s -> miss [style=bold,color=blue,label=" req.\n is_hitmiss"]
	lookup:hfp:s -> pass [style=bold,color=red,label=" req.\n is_hitpass"]
	lookup:h:s -> lookup2 [style=bold,color=green]

	lookup2:deliver:s -> deliver:n [style=bold,color=green]
	lookup2:pass:s -> pass [style=bold,color=red]

	/* cnt_miss */
	subgraph xcluster_miss {
		miss [
		      shape=record
		      label="{cnt_miss:|{vcl_miss\{\}|req.*}|{fail|<fetch>fetch|<synth>synth|<rst>restart|<pass>pass}}"
		]
	}
	miss:fetch:s -> FETCH [style=bold,color=blue]
	miss:pass:s -> pass [style=bold,color=red]

	/* cnt_pass */
	subgraph xcluster_pass {
		pass [
		      shape=record
		      label="{cnt_pass:|{vcl_pass\{\}|req.*}|{fail|<fetch>fetch|<synth>synth|<rst>restart}}"
		]
	}
	pass:fetch:s -> FETCH [style=bold, color=red]

	/* cnt_pipe */
	subgraph xcluster_pipe {
		pipe [
		      shape=record
		      label="{cnt_pipe:|filter req.*-\>bereq.*|{vcl_pipe\{\}|{req.*|bereq.*}}|{fail|<pipe>pipe|<synth>synth}}"
		]
		pipe_do [
			 shape=ellipse
			 label="send bereq,\ncopy bytes until close"
		]
		pipe:pipe -> pipe_do [style=bold,color=orange]
	}
	pipe_do -> DONE [style=bold,color=orange]

	/* cnt_restart */
	subgraph xcluster_restart {
		restart [
			shape=record
			color=grey
			fontcolor=grey
			label="{cnt_restart:|{fail|<ok>ok?|<max>max_restarts?}}"
		]
	}
	RESTART -> restart [color=purple]
	restart:ok:s -> recv
	restart:max:s -> err_restart [color=purple]
	err_restart [label="SYNTH",shape=plaintext]

	/* cnt_recv() */
	subgraph xcluster_recv {
		recv [
		      shape=record
		      label="{cnt_recv:|{vcl_recv\{\}|req.*}|{fail|<hash>hash|<purge>purge|<pass>pass|<pipe>pipe|<restart>restart|<synth>synth|<vcl>vcl}}"
		      ]
		recv:hash -> hash [style=bold,color=green]
		hash [
		      shape=record
		      label="{cnt_recv:|{vcl_hash\{\}|req.*}|{<lookup>lookup}}"
		      ]
	}
	recv:pipe -> hash [style=bold,color=orange]
	recv:pass -> hash [style=bold,color=red]
	hash:lookup:w -> lookup [style=bold,color=green]
	hash:lookup:s -> purge:top:n [style=bold,color=purple]
	hash:lookup:s -> pass [style=bold,color=red]
	hash:lookup:e -> pipe [style=bold,color=orange]

	recv:purge:s -> hash [style=bold,color=purple]

	recv:vcl:s -> vcl_label
	vcl_label [label="switch to vcl\nLABEL",shape=plaintext]

	/* cnt_purge */
	subgraph xcluster_purge {
		purge [
		       shape=record
		       label="{<top>cnt_purge:|{vcl_purge\{\}|req.*}|{fail|<synth>synth|<restart>restart}}"
		]
	}
}
